一、認證
1.Browsable API頁面認證與JWT認證比較
1.Browsable API頁面認證
- 指定permission_classes
- 添加rest_framework.urls路由
2.Json Web Token認證
- 最常用的認證方式
- Session認證
- Token認證
- Session認證
- 保存在服務端,增加服務器開銷
- 分布式架構中,難以維持Session會話同步
- CSRF攻擊風險
- Token認證
- 保存在客戶端
- 跨語言、跨平台
- 拓展性強
- 鑒權性能高
- JWT
- 由三部分組成
- header、playload、signature
- 由三部分組成
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhemF6aWUiLCJhdWQiOiJ1c2VycyIsImlhdCI6MTU5NTY3NTA1NiwiZXhwIjoxNTk2Mjc5ODU2LCJ1c2VyX2lkIjozMDI3NTQxfQ.vJPcwpw4_WBLGBkXO3SUPbyfgDzk4S3FwWzJrCtvhwA
-
- header
- 聲明類型
- 聲明加密算法,默認為HS256
- base64加密,可以解密
- playload
- 存放過期時間、簽發用戶等
- 可以添加用戶的非敏感信息
- base64加密,可以解密
- signature
- 有三部分組成
- 使用base64加密之后的header+.+使用base64加密之后的playload+.+使用HS256算法加密,同時secret加鹽處理
- header
2.Browsable API頁面認證
1.源碼
'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication' ]
2.說明
BasicAuthentication:基本的用戶密碼認證
SessionAuthentication:session會話認證
SessionAuthentication和BasicAuthentication二者缺一不可,相輔相成,我們也可以在此基礎上增加別的認證,如:token認證、微信/QQ第三方認證、LADP認證
在authentication.py模塊中,除了上面這兩種,還有其它的認證方式可供選擇:
3.指定視圖下認證
authenticcation_classes = [] # 列表中添加對應的認證方式
一般不需要指定視圖下進行認證,往往一個項目下只會使用一種認證方式
4.創建超級管理員
命令行
python manage.py createsuperuser --username USERNAME --email EMAIL
5.添加路由
這里提供的是一種前后端不分離的登錄,后面會舍棄掉
在全局下的urls.py中添加如下代碼
from django.contrib import admin
from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('rest_framework.urls')) ]
我們可以去看看rest_framework下的urls.py
配置了之后就已經提供了登錄和登出的接口
6.登錄
2.JWT認證
1.jwt實現原理
1.安裝jwt
pip install -i https://pypi.douban.com/simple pyjwt
2.引入jwt
import jwt
3.指定header和playload
header一般不需要指定,使用默認值即可
指定后端需要存放的一些非敏感信息
playload = { 'username': '小公瑾', 'age': 18 }
3.服務端創建token令牌
token = jwt.encode(playload, key='user') # key由服務器來規定
4.服務端對前端用戶傳遞的token進行解密
res = jwt.decode(token, key='user')
2.drf的token認證實現方法
1.安裝djangorestframework-jwt
pip install -i https://pypi.douban.com/simple djangorestframework-jwt
2.全局配置指定JWT Token認證
一定要注意列表是有優先級的,需要把該認證放到第一個位置
REST_FRAMEWORK = { # 認證方式 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication' ] }
3.根路由配置user模塊
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('user/', include('user.urls')) ]
4.user子模塊下添加路由
from django.urls import path from rest_framework_jwt.views import obtain_jwt_token urlpatterns = [ path('login/', obtain_jwt_token) ]
5.驗證結果
6.重寫jwt_response
1).重寫jwt_response_payload_handler
def jwt_response_payload_handler(token, user=None, request=None): return { 'user_id': user.id, 'username': user.username, 'token': token }
2).注冊重寫的方法
將rest_framework_jwt中的全局配置進行覆蓋,源碼配置如下:
3).在全局配置中重寫配置
JWT_AUTH = { 'JWT_RESPONSE_PAYLOAD_HANDLER': 'utils.jwt_handler.jwt_response_payload_handler' }
7.驗證結果
8.其它配置和說明
1).其它接口認證
- 前端用戶訪問一些需要認證之后的接口,那么默認需要在請求頭中攜帶參數
- 請求key默認為Authorization,值為前綴+空格+token值,如:
JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhemF6aWUiLCJhdWQiOiJ1c2VycyIsImlhdCI6MTU5NTY3NTA1NiwiZXhwIjoxNTk2Mjc5ODU2LCJ1c2VyX2lkIjozMDI3NTQxfQ.vJPcwpw4_WBLGBkXO3SUPbyfgDzk4S3FwWzJrCtvhwA
2).修改token過期時間
覆蓋rest_framework_jwt配置
import datetime JWT_AUTH = { 'JWT_RESPONSE_PAYLOAD_HANDLER': # token過期時間默認為300秒,這里可以自定義 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1), }
二、授權
1.源碼
'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.AllowAny', ]
2.說明
源碼中只提供了AllowAny的授權,它表示不限制任何權限,一般情況下,這種授權不會滿足要求,我們可以看看permissions.py模塊下提供的其它授權
AllowAny:任意權限
IsAuthenticated:允許登錄后擁有權限
IsAdminUser:管理員權限
IsAuthenticatedOrReadOnly:未登錄下只允許瀏覽
3.指定視圖下權限
permission_classes = [permissions.AllowAny]
permissions需要引入
from rest_framework import permissions