一.drf的Token認證機制
1.配置
settings里加入
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication', 前兩個用來生成 Token
'rest_framework.authentication.TokenAuthentication', 這個可以用來檢索
INSTALLED_APPS中加入
'rest_framework.authtoken',
同時配置 url
drf自帶的token認證模式,生成token
from rest_framework.authtoken import views
url(r'^api-token-auth/', views.obtain_auth_token)
2.生成Token
我是在 Postman上檢測
在 body 寫入已註冊過的用戶名和密碼
輸入此 url 發送Post請求
注意:一定要選中旁邊 JSON(application/json)!!!
之後便會返回生成 Token如下
{"token":"bd8807c2b0d3b56cd0b8adb56365c2f5055eadbd"}
同時在數據庫中也會生成新表 authtoken_token
此表和用戶表關聯,生成 Token 存入 key字段
3.概述
先來一段題外話
Token是什麼?
一般來說,每次登陸時用戶都必須輸入用戶名和密碼,頻繁登陸就會很麻煩
所以Token應運而生,當第一次輸入後,服務端就會生成token並返回給客戶端,
這相當於一個憑證,而下次客戶端登陸時只要拿此token便可直接登陸,方便許多
drf的token認證缺點:最大的缺點就是token永久有效,即一旦發送永遠能夠登入
4.檢索
究竟怎樣實現服務端只要到 token,就開啓大門呢?
依舊在 Postman上實驗
url 隨意只要能通
使用 Get方法
在 Headers處寫入
Authorization Token 生成的token
注意 Token與生成的 token有一個空格
在代碼處設置斷點如下圖
執行程序 runserver
可以看到 打印出來用戶對象的用戶名
即獲得了用戶對象
在生成 Token時,中間middware中間件幫我們做了很多
首先執行進入HttpRequest,執行 process_request, 然後是process_view,
最終返回 HttpResponse
解密過程由中間件完成,首先將 Token和key序列化排序,分割並獲得token值
再在 數據庫中比對 token 獲得該對象
二.drf與JWT認證
1.配置
settings
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication'
),}
url配置
from rest_framework_jwt.views import obtain_jwt_token
jwt的認證接口
url(r'^login/', obtain_jwt_token)
2.生成 Token
3.設置 Token生效時間
settings
JWT_AUTH = {
'jwt_EXPIRATION_DELTA': datetime.timedelta(days=7),
'JWT_AUTH_HEADER_PREFIX': 'JWT',
}
設置有效時間爲 7 天
附加:自定義用戶登陸認證
setting
AUTHENTICATION_BACKENDS = (
'users.views.CustomBackend',
)
視圖函數所在位置
views
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
class CustomBackend(ModelBackend):
"""
自定義用戶認證,重寫認證方法
"""
def authenticate(self, request, username=None, password=None, **kwargs):
try:
user = User.objects.get(Q(username=username) | Q(mobile=username))
if user.check_password(password):
return user
except:
return None