一.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