【DRF框架】認證組件
阿新 • • 發佈:2018-12-16
成功 color t對象 是否 query als post tex response
DRF框架的認證組件
核心代碼: self.perform_authentication(request)
框架自帶模塊: from rest_framework import authentication
認證組件的返回值:request.user
自定義的認證組件的鉤子方法authenticator.authenticate(self) ;返回值是元組(user,auth)
from rest_framework import authentication
from rest_framework import authentication class BaseAuthentication(object):def authenticate(self, request): # 必須重寫該方法,返回元組(user,auth) return (user_obj,token) class BasicAuthentication(BaseAuthentication): class SessionAuthentication(BaseAuthentication): class TokenAuthentication(BaseAuthentication): class RemoteUserAuthentication(BaseAuthentication):
基於BaseAuthentication類的認證
# myauth.py
from rest_framework import authentication
from AuthDemo.models import UserTable
from rest_framework.exceptions import AuthenticationFailed # 用於拋出異常
# 基於BaseAuthentication類的認證
class AuthoDemo(authentication.BaseAuthentication):
‘‘‘驗證GET請求是否攜帶Token‘‘‘
def authenticate(self, request):
# 通過/user/test/?token="xxx" 獲取token
token = request.query_params.get("token","")
# 如果token不存在
if not token:
# 拋出異常
raise AuthenticationFailed("token不存在")
# token存在,驗證token
user_obj = UserTable.objects.filter(token=token).first()
if user_obj:
# 驗證通過,必須返回元組,(user,token)
return (user_obj,token)
# 認證不通過拋出異常
raise AuthenticationFailed("token錯誤")
# views.py
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import UserTable
import uuid
from utils.myauth import AuthoDemo
from rest_framework import authentication
# Create your views here.
# 註冊視圖
class RegisterView(APIView):
def post(self,request):
# 獲取提交的用戶名和密碼
username = request.data.get(‘username‘)
password = request.data.get(‘password‘)
# 創建對象
UserTable.objects.create(username=username,password=password)
# 返回結果
return Response("註冊成功!")
# 登陸視圖
class LoginView(APIView):
def post(self,request):
# 獲取提交的用戶名和密碼
username = request.data.get(‘username‘)
password = request.data.get(‘password‘)
# 驗證用戶名密碼是否正確
user_obj = UserTable.objects.filter(username=username,password=password).first()
if user_obj:
# 驗證通過,寫入Token並保存
token = uuid.uuid4()
user_obj.token = token # 為對象的token字段寫入隨機字符串
user_obj.save()
# 返回token
return Response(token)
else:
return Response("用戶名密碼不正確")
# 認證的測試視圖
class TestView(APIView):
authentication_classes = [AuthoDemo,]
def get(self,request):
print(request.user) # 獲取用戶對象
print(request.auth) # 獲取token
print(request.user.username) # 獲取用戶對象的名字
return Response("認證測試接口")
源碼流程
# 1、封裝request對象
def dispatch(self, request, *args, **kwargs):
request = self.initialize_request(request, *args, **kwargs)
# 1.1
def initialize_request(self, request, *args, **kwargs):
parser_context = self.get_parser_context(request)
return Request(
request,
parsers=self.get_parsers(),
# 返回認證類的實例化對象列表:[auth() for auth in self.authentication_classes]
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
# 1.2
class APIView(View):
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
from rest_framework import authentication # 查看自帶的認證類
class ApiView(View):
# 2、認證組件
self.perform_authentication(request)
# 權限組件
self.check_permissions(request)
# 節流組件
self.check_throttles(request)
# 2.1、開始認證
def perform_authentication(self, request):
request.user
# 2.2、調用Request.user
class Request(object):
def __init__(self, request, authenticators=None):
self.authenticators = authenticators or ()
@property
def user(self):
if not hasattr(self, ‘_user‘):
with wrap_attributeerrors():
# 2.3、
self._authenticate()
return self._user
# 2.3、讀取認證對象列表
def _authenticate(self):
for authenticator in self.authenticators:
try:
# 對每個進行驗證,異常則全部終止,若返回None,則繼續循環
user_auth_tuple = authenticator.authenticate(self)
except exceptions.APIException:
self._not_authenticated()
raise
if user_auth_tuple is not None:
# 給request賦值user
self._authenticator = authenticator
self.user, self.auth = user_auth_tuple
# 通過直接退出循環
return
# 全都沒有通過則設置匿名用戶
self._not_authenticated()
# 認證類實例
class BasicAuthentication(BaseAuthentication):
def authenticate(self, request):
"""
Returns a `User` if a correct username and password have been supplied
using HTTP Basic authentication. Otherwise returns `None`.
"""
pass
return self.authenticate_credentials(userid, password, request)
def authenticate_credentials(self, userid, password, request=None):
"""
Authenticate the userid and password against username and password
with optional request for context.
"""
user = authenticate(request=request, **credentials)
if user is None:
raise exceptions.AuthenticationFailed(_(‘Invalid username/password.‘))
if not user.is_active:
raise exceptions.AuthenticationFailed(_(‘User inactive or deleted.‘))
return (user, None)
【DRF框架】認證組件