1. 程式人生 > >rest-framework的認證組件

rest-framework的認證組件

書籍 sca all msg models com authent 賦值 exception

認證組件

1.登錄認證(與組件無關):

首先要在model表內添加用戶表和token表:

from django.db import models

# Create your models here.
class User(models.Model):
    name=models.CharField(max_length=32)
    pwd=models.CharField(max_length=32)

class Token(models.Model):
    user=models.OneToOneField("User",on_delete=models.CASCADE)
    token
=models.CharField(max_length=128)
import hashlib,time
def get_random_str(user):
    ctime=str(time.time())
    md5=hashlib.md5(bytes(user,encoding="utf-8"))
    md5.update(bytes(ctime,encoding="utf-8"))

    return md5.hexdigest()


class LoginView(APIView):
    def post(self,request):
        name
=request.data.get("name") pwd=request.data.get("pwd") user=User.objects.filter(name=name,pwd=pwd).first() res={"state_code":1000,"msg":None} if user: random_str=get_random_str(user.name) toekn=Token.objects.update_or_create(user=user,defaults={"token
":random_str}) res["token"]=random_str else: res["state_code"]=1001 #錯誤的狀態碼 res["msg"]="用戶名密碼錯誤!" return Response(json.dumps(res))

2.局部認證:

# Author:Jesi
# Time : 2018/10/6 18:14
from .models import *
from rest_framework.authentication import BaseAuthentication

from rest_framework import exceptions
class  TokenAuth(BaseAuthentication):
    def authenticate(self,request):
        ‘‘‘函數名必須叫authenticate‘‘‘
        # 驗證條件根據需求設置(此示例為需要有token值)
        token=request.GET.get("token")
        token_obj=Token.objects.filter(token=token).first()
        if not token_obj:
            # 如果驗證失敗,需要跑出AuthenticationFailed錯誤
           raise exceptions.AuthenticationFailed("驗證失敗!")
        else:
            # 如果驗證成功,需要返回一個元組,分別是用戶以及驗證類的實例對象,然後內部會賦值給request.user和request.auth
            return token_obj.user.name,token_obj.token

    def authenticate_header(self,request):
        #加上上面的基礎類繼承,那麽這個header方法就可以不用寫了。
        pass

在視圖中只需要加一句就OK了。

class BookView(APIView):
    authentication_classes = [TokenAuth]  # 註意,值為一個列表,可以放多個認證組件類名 
    def get(self,request):
        print(request.user)   #token_obj.user.name
        print(request.auth)   #token_obj.token
        book_list=Book.objects.all()
        # bs=BookSerializers(book_list,many=True)
        bs2=BookModelSerializers(book_list,many=True,context={request: request})
        # return Response(bs.data)
        return Response(bs2.data)

這裏打印的2個request.user,request.auth分別就是上面認證類返回的token_obj.user.name和token_obj.token。是一個元組。

3.全局配置:

將認證類放到一個util.py的一個額外文件下:

# Author:Jesi
# Time : 2018/10/6 18:14
from .models import *
from rest_framework.authentication import BaseAuthentication

from rest_framework import exceptions
class  TokenAuth(BaseAuthentication):
    def authenticate(self,request):
        token=request.GET.get("token")
        token_obj=Token.objects.filter(token=token).first()
        if not token_obj:
           raise exceptions.AuthenticationFailed("驗證失敗!")
        else:
            return token_obj.user.name,token_obj.token

    def authenticate_header(self,request):
        #加上上面的基礎類繼承,那麽這個header就可以不用寫了。
        pass

然後在settings裏面進行一個配置:

REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.utils.TokenAuth"]
}

這樣全局就都擁有了認證的組件。如果要查看書籍,作者等操作的時候需要帶上token通過認證類的驗證才可以。

http://127.0.0.1:8000/books/?token=7f9038f36213a9e6aa6c3ad51043d9d0

最後:

這樣配置之後,每個視圖類都要經過認證成功之後才能執行下一步,如果有某些方法不需要認證,如login函數,則需要在login函數中單獨加入一個配置屬性:

authentication_classes = [] #自己的類裏有的話就調用此類的配置,為空既什麽都不做

rest-framework的認證組件