django-rest-framework的认证流程源码简单解析
django-rest-framework的认证流程源码简单解析
在编写购物车功能时需要实现未登录状态下的添加购物车功能,但是django的认证在进入视图函数前就会进行,如果未登陆的话请求根本进不到接口(在使用
JWT验证的时候),由于前段会携带JWT字段但却没有携带值,导致认证功能报错。
那么如何解决呢?
perform_authentication()这个函数是在程序进入视图函数前运行的
def initial(self, request, *args, **kwargs): self.format_kwarg = self.get_format_suffix(**kwargs) neg = self.perform_content_negotiation(request) request.accepted_renderer, request.accepted_media_type = neg version, scheme = self.determine_version(request, *args, **kwargs) request.version, request.versioning_scheme = version, scheme self.perform_authentication(request) # self.check_permissions(request) self.check_throttles(request)
这个函数 return request.user
这里的request.user是个property装饰的方法
@property def user(self): if not hasattr(self, '_user'): self._authenticate() return self._user
def _authenticate(self): for authenticator in self.authenticators: try: user_auth_tuple = authenticator.authenticate(self) #重点 except exceptions.APIException: self._not_authenticated() raise if user_auth_tuple is not None: self._authenticator = authenticator #验证用户的功能 self.user, self.auth = user_auth_tuple return self._not_authenticated()
其中的self.authenticators是我们在视图类中定义的authentication_classes,即身份认证类。
最终,认证类中的authenticate方法会返回一个用户对象给request.user,我们的用户就是这么获得的。
而在后面的 self.check_permissions(request) 方法,是进行权限验证的,最终在我们定义的权限类中的 has_permission 方法返回
return request.user and request.user.is_authenticated
言归正传,如果想实现在不登录下的进入视图,那么我们只需要重写perform_authentication()方法,即
def perform_authentication(self, request): """ 重写父类的用户验证方法,不在进入视图前就检查JWT """ pass
之后再在视图函数中判断用户是否登录
try: user = request.user except Exception as e: user = None if user and user.is_authenticated: """如果用户登录的操作""" else: """如果用户没登录的操作"""
以上