用户登录成功后,生成一个随机字符串和用户绑定,存在用户表里,这个随机字符串就叫token
用户每次请求都带这个token,来判断用户是否登录
源码流程:
APIView中的dispatch方法
做分发之前先执行initial方法。把版本信息,认证,权限等信息放入request中------只有认证通过,并且有权限之后,才走get或post的逻辑。
APIView中的initial方法
APIView中的perform_authentication方法
Request类中的user属性方法 ,APIView中将原生request封装在Request类中。
访问request.user,如果没有request.user,就执行_authenticate方法
self表示APIView封装之后的request对象,_authenticate会执行每个配置的认证类对象中的authenticate方法,只要有一个认证类通过
就不继续执行后面的认证类,request.user和request.auth中就有值了
上面代码中的self.authenticators==[auth() for auth in self.authentication_classes] ,为什么呢?请看下面
Request类的初始化方法
APIView类中dispatch方法中调用的initialize_request方法
可以看出我们的认证类放在配置文件中"DEFAULT_AUTHENTICATION_CLASSES",是一个列表。
简单的认证demo
项目下的utils目录里创建auth.py
from rest_framework.exceptions import AuthenticationFailed from authDemo.models import User from rest_framework.authentication import BaseAuthentication class MyAuth(BaseAuthentication): def authenticate(self, request): # 做认证,看用户是否登录 # 从url过滤条件中拿到token # 去数据库看token是否合法 # 合法的token能获取到用户信息 token = request.query_params.get("token", "") if not token: raise AuthenticationFailed("没有携带token") user = User.objects.get(token=token) if not user: raise AuthenticationFailed("token不合法") return (user, token)
在配置文件中配置刚刚写好的auth认证类【配置文件中是全局配置,所有的视图都要走这个认证】
REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["utils.auth.MyAuth", ], }
视图中使用认证类【在需要认证类的View中配置authentication_classes只在该类中生效,是局部配置】:
from utils.auth import MyAuth class DemoView(APIView): authentication_classes = [MyAuth, ] # 局部配置,只是该视图走认证类 def get(self, request): return Response("认证demo")
当然,框架给我们提供好了一系列认证类,
from rest_framework import authentication
都在authentication中