rest-framework的認證組件
阿新 • • 發佈:2018-10-06
書籍 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的認證組件