1. 程式人生 > >drf認證元件

drf認證元件

(1)model層

class UserInfo(models.Model):
    name = models.CharField(max_length=32)
    # 寫choice
    user_choice = ((0, '普通使用者'), (1, '會員'), (2, '超級使用者'))
    # 指定choice,可以快速的通過數字,取出文字使用get_user_type_display()
    user_type = models.IntegerField(choices=user_choice, default=0)
    pwd = models.CharField(max_length=32)


# 使用者token class UserToken(models.Model): token = models.CharField(max_length=64) user = models.OneToOneField(to=UserInfo)

(2)新建認證類(驗證通過return兩個引數)

from app01 import models
from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication


# 用drf的認證,寫一個類 class LoginAuth(BaseAuthentication): # 函式名一定要叫authenticate,接收必須兩個引數,第二個引數是request物件 def authenticate(self, request): # 從request物件中取出token(也可以從其它地方取) token = request.query_params.get('token') # 去資料庫過濾,查詢 ret = models.UserToken.objects.filter(token=token).first()
if ret: # 能查到,說明認證通過,返回空 # ret.user就是當前登入使用者物件 return ret.user, ret # 如果查不到,拋異常 raise exceptions.APIException('您認證失敗')

(3)view層

from django.shortcuts import render
from rest_framework.views import APIView
from app01 import models
from django.core.exceptions import ObjectDoesNotExist
import hashlib
import time
from django.http import JsonResponse
from app01 import MySerializer
from rest_framework import exceptions

def get_token(name):
    # 生成一個md5物件
    md5 = hashlib.md5()
    # 往裡新增值,必須是bytes格式
    # time.time()生成時間戳型別,轉成字串,再encode轉成bytes格式
    md5.update(str(time.time()).encode('utf-8'))
    md5.update(name.encode('utf-8'))
    return md5.hexdigest()

class Login(APIView):
    #-區域性禁用,在檢視類中加一行:
    authentication_classes = []
    def post(self, request, *args, **kwargs):
        response = {'status': 100, 'msg': '登入成功'}
        name = request.data.get('name')
        pwd = request.data.get('pwd')
        try:
            user = models.UserInfo.objects.get(name=name, pwd=pwd)
            # 校驗通過,登入成功,生成一個隨機字串(身份標識)token
            token = get_token(name)
            # 儲存到資料庫
            # update_or_create更新或者建立
            models.UserToken.objects.update_or_create(user=user, defaults={'token': token})
            response['token'] = token
        except ObjectDoesNotExist as e:
            response['status'] = 101
            response['msg'] = '使用者名稱或密碼錯誤'
        except Exception as e:
            response['status'] = 102
            # response['msg']='未知錯誤'
            response['msg'] = str(e)
        return JsonResponse(response, safe=False)


from rest_framework.request import Request
from app01.MyAuth import LoginAuth
class Books(APIView):
    #-區域性使用,在檢視類中加一行:
    # 列表中,類名不能加括號
    # authentication_classes = [LoginAuth, ]

    def get(self, request, *args, **kwargs):
        # 只要通過認證,就能取到當前登入使用者物件
        print(request.user)
        response = {'status': 100, 'msg': '查詢成功'}
        ret = models.Book.objects.all()
        book_ser = MySerializer.BookSerializer(ret, many=True)
        response['data'] = book_ser.data
        return JsonResponse(response, safe=False)



-全域性使用
    -在setting中配置:
      REST_FRAMEWORK={
         'DEFAULT_AUTHENTICATION_CLASSES':['app01.MyAuth.LoginAuth',]
       }