DRF 版本 认证

DRF 版本 认证

DRF的版本

1. 版本控制的作用

  • 为了区别新旧版本,所以我们对版本进行控制,

2.查看源码流程

  • 执行APIView的方法,APIView返回View中的view函数,然后调用的dispatch方法

    img

    执行self.initial方法之前是各种赋值,包括request的重新封装赋值,下面是路由的分发

    img

    version版本信息赋值给了 request.version 版本控制方案赋值给了 request.versioning_scheme

    其实这个版本控制方案就是我们配置的版本控制的类~

    也就是说,APIView通过这个方法初始化自己提供的组件~~

    框架提供的哪些版本的控制方法在rest_framework.versioning里

    img

详细用法,这里是全局使用

1.在setting.py中配置

REST_FRAMEWORK = {
    # 默认使用的版本控制类
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
    # 允许的版本
    'ALLOWED_VERSIONS': ['v1', 'v2'],
    # 版本使用的参数名称
    'VERSION_PARAM': 'version',
    # 默认使用的版本
    'DEFAULT_VERSION': 'v1',
}

2. urls.py中配置

urlpatterns = [
    url(r"^versions", MyView.as_view()),
    url(r"^(?P<version>[v1|v2]+)/test01", TestView.as_view()),
]

3.视图view

class TestView(APIView):
    def get(self, request, *args, **kwargs):
        print(request.versioning_scheme)
        ret = request.version
        if ret == "v1":
            return Response("版本v1的信息")
        elif ret == "v2":
            return Response("版本v2的信息")
        else:
            return Response("根本就匹配不到这个路由")

DRF 认证

  • 作用

    由于客户端每次给服务端发请求,http是无状态的,导致每次都是新的请求

    服务端要对每次来的请求进行认证,查看用户是否登录,以及登录的是谁

    以往是通过加装饰器,或者在中间件来进行认证,但是DRF给我们提供了

源码流程

执行APIView的方法,APIView返回View中的view函数,然后调用的dispatch方法,然后执行initial方法

img

点击perform_authentication方法

img

这里的request是封装之后的request,所有要在Request的实例中

img

点击查看

img

认证的详细用法

  • model.py 简单写一些字段,

    class UserInfo(models.Model):
        username = models.CharField(max_length=32)
        token = models.UUIDField()
    
  • view.py

    class UserView(APIView):
        def post(self, request, *args, **kwargs):
            username = request.data["username"]
            UserInfo.objects.create(username=username, token=uuid.uuid4())
            return Response("注册成功")
    
  • 开始做认证

  • 先写一个认证类

    # 注意我们这个认证的类必须实现的方法以及返回值
    class MyAuth(BaseAuthentication):
    
        def authenticate(self, request):
            request_token = request.query_params.get("token", None)
            if not request_token:
                raise AuthenticationFailed({"code": 1001, "error": "缺少token"})
            token_obj = UserInfo.objects.filter(token=request_token).first()
            if not token_obj:
                raise AuthenticationFailed({"code": 1001, "error": "无效的token"})
            return token_obj.username, token_obj
    
  • 视图级别的认证

    class TestAuthView(APIView):
        authentication_classes = [MyAuth, ]
    
        def get(self, request, *args, **kwargs):
            return Response("测试认证")
    
  • 全局认证

    REST_FRAMEWORK = {
        # 默认使用的版本控制类
        'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
        # 允许的版本
        'ALLOWED_VERSIONS': ['v1', 'v2'],
        # 版本使用的参数名称
        'VERSION_PARAM': 'version',
        # 默认使用的版本
        'DEFAULT_VERSION': 'v1',
        # 配置全局认证
        'DEFAULT_AUTHENTICATION_CLASSES': ["BRQP.utils.MyAuth", ]
    }
    

    全局认证必须认证完成才会执行视图中的方法

原文地址:https://www.cnblogs.com/yuncong/p/10129005.html