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

互联网中的认证:

  • 用户名密码登录
  • 邮箱发送登录链接
  • 手机号接收验证码
  • 只要你能收到邮箱 / 验证码,就默认你是账号的主人

传统认证方式

# models
class UserInfo(models.Models):
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=64)
    
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)

源码分析

#认证中的基类,主要实现authenticateauthenticate_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()
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值