python_restframework(認證組件)
阿新 • • 發佈:2019-05-14
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(認證組件)