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."}
    

      

      

  • 相关阅读:
    剖析Vue原理&实现双向绑定MVVM
    js处理异步的几种方式
    【转】从Vue.js源码看异步更新DOM策略及nextTick
    js中获取css样式属性值
    原生JS节点操作
    圣杯布局和双飞翼布局的作用和区别
    vue自定义插件-弹框
    MongoDB 数据库创建删除、表创建删除、数据增删改查
    Vue组件之间数据交互与通信
    Vue中的计算属性与$watch
  • 原文地址:https://www.cnblogs.com/jabbok/p/10795440.html
Copyright © 2011-2022 走看看