django-rest-framework源码分析2—认证(Authentication)源码解析_authentication authenticate 源码

37 阅读2分钟

class UserToken(models.Models): user = models.OneToOneField(to='UserInfo') token = models.CharField(max_length=64)

views

def md5(user): import hashlib import time ctime = str(time.time()) m = hashlib.md5(bytes(user,enceding='utf-8')) m.update(bytes(ctime,enceding='utf-8')) return m.hexdigest()

class AuthView(APIView): def post(self,request,*args,**kwargs): ret = {"code":'1000','msg':None} try: user = request._request.POST.get('username') pwd = reuqest._request.POST.get('password') obj = models.UserInfo.objects.filter(username=name,password=pwd).first() if not obj: ret['code']='1001' ret['msg']='用户名秘密错误' token = md5(user) models.UserToken.objects.update_or_create(user=obj,default={'token':token}) ret['token']=token except Excepion as e: ret['code']='1002' ret['msg']='请求异常' return JsonResponse(ret)


### 源码分析



#认证中的基类,主要实现**authenticate** 和 **authenticate\_header**方法



class BaseAuthentication: """ 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


#基于用户名和密码的认证



class BasicAuthentication(BaseAuthentication):


#基于session的认证



class SessionAuthentication(BaseAuthentication):


#基于token的认证



class TokenAuthentication(BaseAuthentication): ---


#远程用户认证



class RemoteUserAuthentication(BaseAuthentication): """ REMOTE_USER authentication.

To use this, set up your web server to perform authentication, which will set the REMOTE_USER environment variable. You will need to have 'django.contrib.auth.backends.RemoteUserBackend in your AUTHENTICATION_BACKENDS setting """


#### 认证流程


**authentication\_classes**  
 **请求到dispatch方式**



def dispatch(self, request, *args, **kwargs): """ .dispatch() is pretty much the same as Django's regular dispatch, but with extra hooks for startup, finalize, and exception handling. """ self.args = args self.kwargs = kwargs request = self.initialize_request(request, *args, **kwargs) self.request = request self.headers = self.default_response_headers # deprecate? try: self.initial(request, *args, **kwargs)


**调用self.initial()**



def initial(self, request, *args, **kwargs): self.perform_authentication(request)


**调用 perform\_authentication() 返回request.user**



def perform_authentication(self, request): request.user


\*\*在dispatch中initialize\_request封装了Request \*\*



def initialize_request(self, request, *args, **kwargs): parser_context = self.get_parser_context(request) return Request( request, parsers=self.get_parsers(), authenticators=self.get_authenticators(), negotiator=self.get_content_negotiator(), parser_context=parser_context )


**Request 有方法注解 user 调用\_authenticate 循环认证对象 执行方法**



@property def user(self): if not hasattr(self, '_user'): with wrap_attributeerrors(): 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()


#### 使用方法


* 全局使用


**自定义的认证类可以通过全局设置 放在setting文件中 源码中会读取setting中的**



REST_FRAMEWORK={ 'DEFAULT_AUTHENTICATION_CLASSES'=('自定义的认证类'), 'UNAUTHENTICATED_USER':None, 'UNAUTHENTICATED_TOKEN':None

img img img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取