ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

DRF 认证(2)

2022-01-27 18:04:52  阅读:174  来源: 互联网

标签:authenticate self request 认证 authentication user DRF


self.initial()

这里的request 是封装后的request,传入def initial(self, request, *args, **kwargs)这个方法
def initial(self, request, *args, **kwargs):
    """
    Runs anything that needs to occur prior to calling the method handler.
    """
    self.format_kwarg = self.get_format_suffix(**kwargs)

    # Perform content negotiation and store the accepted info on the request
    neg = self.perform_content_negotiation(request)
    request.accepted_renderer, request.accepted_media_type = neg

    # Determine the API version, if versioning is in use.
    version, scheme = self.determine_version(request, *args, **kwargs)
    request.version, request.versioning_scheme = version, scheme

    # Ensure that the incoming request is permitted
    # 身份认证
    self.perform_authentication(request)
    # 检查权限
    self.check_permissions(request)
    # 流量限速
    self.check_throttles(request)

self.perform_authentication(request)

def perform_authentication(self, request):
    """
    Perform authentication on the incoming request.

    Note that if you override this and simply 'pass', then authentication
    will instead be performed lazily, the first time either
    `request.user` or `request.auth` is accessed.
    """
    request.user

他返回的是新封装request的user属性。那我们就得看下他源码是如何封装这个属性,以及user这个属性表示什么

@property
def user(self):
    """
    Returns the user associated with the current request, as authenticated
    by the authentication classes provided to the request.
    
    返回与当前请求关联的经过身份验证的用户,提供给请求的身份验证
    """
    # 判断如果_user 不在request中的话,执行 self._authenticate()这个方法
    if not hasattr(self, '_user'):
        with wrap_attributeerrors():
            # 执行认证方法
            self._authenticate()
    return self._user

我们可以看到他其实还是执行了self._authenticate()。我们还是要看下他的这个authenticate()方法。

self._authenticate()

def _authenticate(self):
    """
    Attempt to authenticate the request using each authentication instance
    in turn.
    """
    for authenticator in self.authenticators:
        try:

            # 执行认证类的authenticate方法
            # 这里分三种情况
            # 1.如果authenticate方法抛出异常,self._not_authenticated()执行
            # 2.有返回值,必须是元组:(request.user,request.auth)
            
            
            
            # 认证类的实例执行authenticate()这个方法,这个可以重写自己的代码逻辑
            user_auth_tuple = authenticator.authenticate(self)
        except exceptions.APIException:
            self._not_authenticated()
            raise

        # 3.返回None,表示当前认证不处理,等下一个认证来处理
        if user_auth_tuple is not None:
            self._authenticator = authenticator
            # 返回值对应示例中的token_obj.user和token_obj
            self.user, self.auth = user_auth_tuple
            return

    self._not_authenticated()

小结

  1. 这里他将执行每一个认证类的实例的authenticate()方法,也就是说如果要写认证类的话是必须写这个方法的
  2. 必须要求返回元祖,然后元祖不为空时就将元祖内的user赋值给self.user,其实也就是侧面赋值给了self._user,
    返回到self.perform_authentication(request)这里,其实也就是返回了这个self._user,使得我们认证知道请求是谁,是否登录的作用

def authenticate(self, request)

class ForcedAuthentication:
    """
    This authentication class is used if the test client or request factory
    forcibly authenticated the request.
    """

    def __init__(self, force_user, force_token):
        self.force_user = force_user
        self.force_token = force_token

    # 一定返回元组
    def authenticate(self, request):
        return (self.force_user, self.force_token)

这个认证工厂要求必须返回元祖

def _not_authenticated(self)

def _not_authenticated(self):
    """
    Set authenticator, user & authtoken representing an unauthenticated request.

    Defaults are None, AnonymousUser & None.
    """
    self._authenticator = None

    if api_settings.UNAUTHENTICATED_USER:
        self.user = api_settings.UNAUTHENTICATED_USER()
    else:
        self.user = None

    if api_settings.UNAUTHENTICATED_TOKEN:
        self.auth = api_settings.UNAUTHENTICATED_TOKEN()
    else:
        self.auth = None

小结

没有身份,相当于匿名用户,默认设置AnonymousUser,如需要单独设置匿名用户返回值,
则编写需要写UNAUTHENTICATED_USER的返回值

所以我们需要认证的时候,需要在每一个认证类中定义authenticate进行验证,并且需要返回元祖

配置认证类

我们知道全局配置都在api_setting中

其中引用了django,settings.py中的REST_FRAMEWORK作为key作为配置,所以全局配置示例:

#全局认证配置
REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES":['API.utils.auth.Authentication',]   #其中写认证的类的路径,不要在views中,这里我放在了utils目录下auth.py中
}

局部使用

局部某个视图不需要认证,则在视图类中加入authentication_classes=[]

authentication_classes = []    #authentication_classes为空,代表不需要认证

匿名设置

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES":['API.utils.auth.Authentication',],  #其中写认证的类的路径,不要在views中,这里我放在了utils目录下auth.py中
    "UNAUTHENTICATED_USER": lambda:"匿名",#匿名用户配置,只需要函数或类的对应的返回值,对应request.user="匿名"
"UNAUTHENTICATED_token": None,#匿名token,只需要函数或类的对应的返回值,对应request.auth=None


}

内置认证类

BaseAuthentication
BaseAuthentication是django rest framework为我们提供了最基本的认证类,正如源码流程一样,该类中其中定义的两个方法authenticate和authenticate_header(认证失败返回的响应头),使用时候重写该两个方法进行认证,正如示例:

class BaseAuthentication(object):
    """
    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```

其他认证类

```python
rest_framework.authentication

BasicAuthentication  #基于浏览器进行认证
SessionAuthentication #基于django的session进行认证
RemoteUserAuthentication #基于django admin中的用户进行认证,这也是官网的示例
TokenAuthentication #基于drf内部的token认证

自定义认证类

继承BaseAuthentication,重写authenticate方法和authenticate_header(pass就可以),authenticate()方法需要有三种情况(返回元祖、出现异常、返回none)。

认证配置

#全局认证
REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES":['API.utils.auth.Authentication',]
}

#局部认证
authentication_classes = [BaseAuthentication,]

#是某个视图不进行认证
authentication_classes =[]

标签:authenticate,self,request,认证,authentication,user,DRF
来源: https://blog.csdn.net/a35155/article/details/122721535

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有