zoukankan      html  css  js  c++  java
  • DRF教程7-token认证

    Authentication

      认证是将一个传入的请求和一组标识凭据相关联的机制,比如请求过来的用户,或者用户登录时携带的token。

      然后权限策略就能使用这些凭据来决定是否允许这个请求。

      REST框架提供了多种开箱即用的方案,也允许你实施自定义的方案。

      认证总是在view的最开始运行,在权限检查之前,在其他任何代码被允许执行之前。

      request.user属性通常会被设为contrib.auth 包下的User类。

      request.auth属性被用做额外的认证信息。比如,作为一个请求签名的认证token

      记住一点,认证机制自己并没有允许或不允许一个传入的请求,它只是简单的标识请求携带的凭据。

    认证方案设定

    全局

    REST_FRAMEWORK = {
        ...
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.TokenAuthentication',
            'rest_framework.authentication.BasicAuthentication'
        ),
    }
    #默认是session+basic
    #对于前后端分离的项目,session认证一般删掉,使用token,basic是必须放在这里的。
    #在settings里设置默认认证类,然后会自上而下拿着请求来验证,然后使用第一个成功认证的类返回用户对象request.user (用户信息)和request.auth(认证信息)。
    #如果没有类认证,request.user 会被设为 django.contrib.auth.models.AnonymousUser一个实例,request.auth 会设置为 None.
    

    局部

    from rest_framework.authentication import SessionAuthentication, BasicAuthentication
    from rest_framework.permissions import IsAuthenticated
    from rest_framework.response import Response
    from rest_framework.views import APIView
    
    class ExampleView(APIView):
        authentication_classes = (SessionAuthentication, BasicAuthentication)
        permission_classes = (IsAuthenticated,)
    
        def get(self, request, format=None):
            content = {
                'user': unicode(request.user),  # `django.contrib.auth.User` instance.
                'auth': unicode(request.auth),  # None
            }
            return Response(content)
    

      

    Unauthorized and Forbidden responses

     当一个未被认证的请求被拒绝时,有两种合适的error code

    401返回必须包含一个WWW-Authenticate header,指导客户端需要如何认证。

    403返回没有包含WWW-Authenticate header。

    使用哪种返回,取决于认证方案。虽然有多种认证方案在使用,但可能只有一个方案用于决定返回的类型。

    在确定响应类型时,将使用视图上设置的第一个身份验证类

    注意:当一个请求被成功认证时,但还是被拒绝执行请求,这种情况下,不论时哪种认证方案,总是使用403返回。

    authentication.py源码分析

    class BaseAuthentication(object):
        """
        All authentication classes should extend BaseAuthentication.
        """
    
        def authenticate(self, request):
            """
            Authenticate the request and return a two-tuple of (user, token).
            """
            raise NotImplementedError(".authenticate() must be overridden.")
    
        def authenticate_header(self, request):
            """
            Return a string to be used as the value of the `WWW-Authenticate`
            header in a `401 Unauthenticated` response, or `None` if the
            authentication scheme should return `403 Permission Denied` responses.
            """
            pass
    #所有认证类都是基于它扩展
    

      

    BasicAuthentication

    这个方案使用HTTP Basic Authentication,使用用户的username和password进行签名。一般只适合用于测试。

    如果成功认证,它会提供以下凭据:

    • request.user will be a Django User instance.
    • request.auth will be None.

    未认证时返回401,带一个WWW-Authenticate header。比如:

    WWW-Authenticate: Basic realm="api"

    TokenAuthentication

    单单使用一个token-based HTTP认证方案。

    首先需要在认证类设置中包含TokenAuthentication

    此外在INSTALLED_APPS 设置中包含rest_framework.authtoken

    INSTALLED_APPS = (
        ...
        'rest_framework.authtoken'
    )
    

      

    然后要同步数据库,因为rest_framework.authtoken会提供 Django database migrations.

    [root@webmaster mofangsvr]# python3.7 manage.py showmigrations
    
    authtoken
     [ ] 0001_initial
     [ ] 0002_auto_20160226_1747
    cmdb
     [X] 0001_initial
    #有个authtoken的app,有两个migrations没有同步
    
    
    python3.7 manage.py migrate authtoken
    #同步数据
    

      

    然后要创建url

    from rest_framework.authtoken import views
    urlpatterns += [
        path('api-token-auth/', views.obtain_auth_token)
    ]
    #在项目urls.py中加入就行
    

      

    token测试

    # curl -X POST -H "Content-Type:application/json" -d '{"username":"yueju_view","password":"123@abAB"}' http://192.168.10.10:8001/api-token-auth/
    {"token":"e3205a50505096dacb3fbbadc7de79cd95b3af45"}
    #服务端返回了一个token
    #在authtoken_token表中产生了一条数据,和user_id关联,但会发现没有过期时间
    

      

    class SvrprocessconfigTestViewSet(viewsets.ModelViewSet):
    
    
        serializer_class = SvrprocessconfigSerializer
        permission_classes = (IsAuthenticated,)
    #在一个类视图中使用认证权限
    

      

    curl -X GET http://192.168.10.10:8001/cmdb/svrprocess_Test/
    {"detail":"身份认证信息未提供。"}
    #这时无法访问,后台401认证错误
    

      

    curl -X GET http://192.168.10.10:8001/cmdb/svrprocess_Test/ -H 'Authorization: Token e3205a50505096dacb3fbbadc7de79cd95b3af45'
    #带上token,则成功返回数据
    

      

    JWT认证

    http://getblimp.github.io/django-rest-framework-jwt/

    测试方式和token的一样,唯一不一样的就是token串变得长了几倍,然后内容每次都是不一样的。

    去查源码,可以发现是因为在串里加入了时间再进行加密。

    过期时间

    JWT_AUTH = {
        'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=20),
    }
    #jwt设置的默认过期时间是300s,可在项目settings中调整
    #如果过期,则token不再生效。报以下错误
    
    {"detail":"Signature has expired."}
    

      

      

  • 相关阅读:
    POJ 1887 Testing the CATCHER
    HDU 3374 String Problem
    HDU 2609 How many
    POJ 1509 Glass Beads
    POJ 1458 Common Subsequence
    POJ 1159 Palindrome
    POJ 1056 IMMEDIATE DECODABILITY
    POJ 3080 Blue Jeans
    POJ 1200 Crazy Search
    软件体系结构的艺术阅读笔记1
  • 原文地址:https://www.cnblogs.com/jabbok/p/10795440.html
Copyright © 2011-2022 走看看