1. 程式人生 > >python_restframework(認證組件)

python_restframework(認證組件)

ons from 成了 content www objects pass class a 註意

認證組件

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)

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://127.0.0.1:8000/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

python_restframework(認證組件)