jwt 认证
2024-09-05 09:59:48
jwt 认证示意图
jwt 优势
1 没有数据库写操作,高效
2 服务器不存 token,低耗
3 签发检验都是算法,集群
jwt 认证算法:签发与检验
jwt 三段式:头 . 体 . 签名 (head.payload.sgin)
头和体是可逆加密,让服务器可以反解除 user 对象,签名是不可逆加密,保证整个token的安全性的
头体签名三部分,都是采用 json 格式的字符串,进行加密,可逆加密一般采用 base64 算法,不可逆加密一般采用 hash(md5) 算法
头中的内容是基本信息:公司信息,项目组信息,token 采用的加密方式信息
{
"company": "公司信息",
...
}
体中的内容是关键信息:用户主键,用户名,签发是客户端信息(设备号,地址),过期时间
{
"user_id": 1,
...
}
签名中的内容是安全信息:头的加密结果 + 体的加密结果 + 服务器不对外公开的安全吗 进行 md5 加密
{
"head": "头的加密字符串",
"payload": "体的加密字符串",
"secret_key": "安全码"
}
签发
根据登陆请求提交来的 账号 + 密码 + 设备信息 签发 token
- 用基本信息存储 json 字典,采用 base64 算法加密得到 头字符串
- 用关键信息存储 json 字典,采用 base64 算法加密得到 体字符串
- 用头、体加密字符串再加安全码信息存储 json 字典,采用 hash md5 算法加密得到 签名字符串
校验
根据客户端带 token 的请求,反解除 user 对象
- 将 token按“ . ”拆分为三段字符串,第一段头加密字符串,一般不需要做任何处理
- 第二段体加密字符串,要反解出用户主键,通过主键从 User 表中就能得到登陆用户,过期时间和设备信息都是安全信息,确保 token 没过期,且是同一设备来的
- 再用 第一段 + 第二段 + 服务器安全吗 不可逆 md5 加密,与第三段字符串进行碰撞校验,通过后才能代表第二段校验得到的 user 对象就是合法的登陆用户
drf 项目的 jwt 认证开发流程(重点)
- 用账号密码访问登陆接口,登陆接口逻辑中调用 签发 token 算法,得到 token,返回给客户端,客户端自己存到 cookies 中
- 校验 token 的算法应该写在认证类中(在认证类中调用),全局配置给认证组件,所有视图类请求,都会校验,所以请求带来了 token,就会反解出 user 对象,在视图类中用 request.user 就能访问登陆的用户
注意:登陆接口需要做 认证 + 权限 两个局部禁用
drf-jwt 框架基本使用
安装
pip install djangorestframework-jwt
签发 token(登陆接口):视图类已经写好了,配置一下路由就行(urls.py)
# api/urls.py
from rest_framework_jwt.views import ObtainJSONWebToken
urlpatterns = [
# ...
url('^login/$', ObtainJSONWebToken.as_view()),
] # Postman请求:/api/login/,提供username和password即可
校验 token (认证组件):认证类已经写好了,全局配置一下组件就行了(settings.py)
# drf-jwt的配置
import datetime
JWT_AUTH = {
# 配置过期时间
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),
} # drf配置(把配置放在最下方)
REST_FRAMEWORK = {
# 自定义三大认证配置类们
'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework_jwt.authentication.JSONWebTokenAuthentication'],
# 'DEFAULT_PERMISSION_CLASSES': [],
# 'DEFAULT_THROTTLE_CLASSES': [],
}
设置需要登陆才能访问的接口进行测试(views.py)
from rest_framework.permissions import IsAuthenticated
class UserCenterViewSet(GenericViewSet, mixins.RetrieveModelMixin):
# 设置必须登录才能访问的权限类
permission_classes = [IsAuthenticated, ] queryset = models.User.objects.filter(is_active=True).all()
serializer_class = serializers.UserCenterSerializer
测试访问登陆认证接口(Postman)
"""
1)用 {"username": "你的用户", "password": "你的密码"} 访问 /api/login/ 接口等到 token 字符串 2)在请求头用 Authorization 携带 "jwt 登录得到的token" 访问 /api/user/center/1/ 接口访问个人中心
"""
token 刷新机制(了解)
drf-jwt 直接提供刷新功能
"""
1)运用在像12306这样极少数安全性要求高的网站
2)第一个token由登录签发
3)之后的所有正常逻辑,都需要发送两次请求,第一次是刷新token的请求,第二次是正常逻辑的请求
"""
settings.py
import datetime JWT_AUTH = {
# 配置过期时间
'JWT_EXPIRATION_DELTA': datetime.timedelta(minutes=5), # 是否可刷新
'JWT_ALLOW_REFRESH': True,
# 刷新过期时间
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
}
urls.py
from rest_framework_jwt.views import ObtainJSONWebToken, RefreshJSONWebToken
urlpatterns = [
url('^login/$', ObtainJSONWebToken.as_view()), # 登录签发token接口
url('^refresh/$', RefreshJSONWebToken.as_view()), # 刷新toekn接口
]
postman
# 接口:/api/refresh/
# 方法:post
# 数据:{"token": "登录签发的token"}
最新文章
- Spring框架概述
- POI读取Excel常见问题
- zabbix监控系列(3)之zabbix触发器格式配置
- Embed dll Files Within an exe (C# WinForms)—Winform 集成零散dll进exe的方法
- SQL中返回一个字符串在另一个中存在的次数
- HotSpot Builder Utility安装指南
- C#_LINQ(LINQ to Entities)
- java oop
- maven使用笔记一 下载json-lib引发的问题
- EassyMock实践 捕获参数
- 版本号控制-GitHub
- ftp上传文件,本地安装了,服务器上也需要在也安装一个ftp
- python脚本检查TCP端口是否正常
- angular路由操作中'#'字符的解决办法
- .net后台防止API接口被重复请求
- tarjan算法(求强连通子块,缩点)
- 使用python调用email模块发送邮件附件
- CAS的应用场景
- CentOS6.5编译安装Nginx1.8.1+MySQL5.5.48+PHP5.2.17+xcache3.2+ZendOptimizer-3.3.9
- 从mysql导入及导出csv