python_restframework(认证组件)
英语文化交流 > 技术博客 > python_restframework(认证组件)
python_restframework(认证组件)
时间: 分类:技术博客

认证组件

1、 APIview分发

继续apiview函数 进入到 dispatch方法中
    def dispatch(self, request, *args, **kwargs):
        # 新的request请求,  initialize_request
        request = self.initialize_request(request, *args, **kwargs)

2、初始化新的request

def initialize_request(self, request, *args, **kwargs):
    """ Returns the initial request object.  """
    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
    )

3、 进入认证组件 get_authenticators

def get_authenticators(self):
    # self.authentication_classes, 这个是一个列表,用于认证组件使用
    return [auth() for auth in self.authentication_classes]

# 在APIview中,api_settings 是直接从配置文件中导入的
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES

4、 当新的Request通过就继续APIview的dispatch方法

def dispatch(self):
    try:
        #  初始化方法
        self.initial(request, *args, **kwargs)

5、 drf初始化方法

APIview下的方法
def initial(self, request, *args, **kwargs):
    # 认证
    self.perform_authentication(request)
    # 权限
    self.check_permissions(request)
    # 频率
    self.check_throttles(request)

6、进入到初始化认证组件中

def perform_authentication(self, request):
    request.user

7、 初始化的 Request请求

# 导入,找到user这个方法
from rest_framework.request import  Request

# 找到user方法, 使用了property定义成了属性
    @property
    def user(self):
        if not hasattr(self, '_user'):
            with wrap_attributeerrors():
                self._authenticate()
        return self._user

8、继续查找self._authenticate()

def _authenticate(self):
    """
    Attempt to authenticate the request using each authentication instance
    in turn.
    """
    # 这里的self.authenticators 就是第2步的 requset中的authenticators
    # return [auth() for auth in self.authentication_classes]
    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
            # 获取元组 user_auth_tuple, 用户id之类的
            self.user, self.auth = user_auth_tuple
            return

9、认证

# 先定义一个认证方法
import uuid
class Login(APIView):
    def post(self,request, *args, **kwargs):
        user = request.data.get("user")
        pwd = request.data.get("pwd")
        response = {"status": 100, "msg": "登陆成功"}
        user_obj = models.User.objects.filter(user=user, pwd=pwd).first()
        if user_obj:
            token = uuid.uuid4()
            models.Token.objects.create(token=token, user=user_obj)
            response["token"] = token
        else:
            response["status"] = 101
            response["msg"] = "用户名或密码错误"
        return JsonResponse(response, safe=False)

# 在需要被定义认证的类下中写, 需要注意的是,这里最多只能写三个,
# 并且如果AUthUser有返回值,后面的认证组件就不会在执行
    authentication_classes = [AuthUser, ]

10、AuthUser

class AuthUser():
    # 这里定义第8步的 authenticator.authenticate(self),  
    # 类调用方法会自动传self,也就是说 这个self在定义的时候还需要手动传一个值
    def authenticate(self, request):
        token =request.GET.get("token")
        print(token)
        ret = models.Token.objects.filter(token=token).first()
        if ret:
            # 如果登陆成功了 那就直接下一步
            return None
        else:
            raise exceptions.APIException("没有登陆")

11、检验

# 最后在postman这个工具中,用get查询, 如果携带了token就能查出详细的信息,如果没有就返回先登陆
    http://****/bookDetail/2?token=66c4bc0a-2f2a-40a3-81f7-5dcb075e7e3f

12、全局使用auth

# settings.py文件中定义, 所有的组件都可以放在这里

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": [
        'app01.myauth.AuthUser',    # 全局使用认证
    ]
}

13、局部使用

类中直接使用 
    authentication_classes = [AuthUser, ]

14、局部禁用

类中直接使用 
    authentication_classes = []

15、BaseAuthentication

继承基础组件, 也可以不继承
from rest_framework.authentication import BaseAuthentication

# 这个基础组件其实啥也没写, 关键在于就是继承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
随机阅读

Copyright © 2017 英语文化交流 All Rights Reserved.