JWT
# 试用场景,分布式站点的单点登录SSO场景
. 分为三段: 头. 载荷. 签名
1. 第一段: 头部 (json数据进行base64加密)
{
'alg':'HS256', # 加密算法
'typ':'JWT' # 类型
}
2. 第二段: 载荷(payload) json数据进行base64加密
-- 标准中注册声明
-- 公共的声明: 用户相关信息或其他业务需要的必要信息
-- 私有的声明: 提供者和消费者共同定义的声明
3. 第三段: 签名
header, payload, secret
-- 将header and payload (base64后的) 用点连在一起
-- 将上述字符串 HS256进行加密,加密需要一个secret秘钥
-- 将加密后的字符串也用点拼接在后面, 形成jwt
'''
签名: 实际是对头部和载荷内容进行签名,因使用的秘钥,所以保证token不被篡改
{头信息字典,用base64加密}.{载荷信息字典,用base64加密}.{头加密串,载荷加密串,秘钥,采用hash256加密算法}
'''
# 得到JWT后,将jwt存在client, 之后每次需要认证的请求,都要把jwt发送过阿里(可放在header的Authorization)
Django Rest Framework JWT
# django 中使用jwt
# 相当于客户端存储token信息, 需要登录的请求必须携带token 给服务器端
1. 安装
pip install djangorestframework-jwt
2. 配置
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':(
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
)
}
JWT_AUTH = {
# 指明token的有效期
'JWT_EXPIRATION_DELTA':datetime.timedelta(days=1)
}
3. 后端使用
两端代码:
-- 登录签发认证 (基本信息,用户信息,过期时间,秘钥)
-- 验证完成效验 (通过一段效验逻辑效验token,秘钥,过期时间,拿到用户信息)
from rest_framework_jwt.serializers import jwt_encode_handler,jwt_payload_handler
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
# 实例
# 获得用户后,校验密码并签发token
if not user.check_password(password):
return APIResponse(1, '密码错误')
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
return APIResponse(0, 'ok', results={
'username': user.username,
'mobile': user.mobile,
'token': token
})
4. 前端使用
// 判断是否登录成功
if (response.data.status == 0) {
let token = response.data.results.token;
this.$cookies.set('token', token, 24 * 60 * 60);
let username = response.data.results.username;
this.$cookies.set('username', username, 24 * 60 * 60);
this.$alert('欢迎回来!', '登录成功!', {
confirmButtonText: '确定',
callback: () => {
// 登录成功,跳转hi主页
this.$router.push('/');
}
})
} else {
this.username = '';
this.password = '';
}
if (status == 0) {
let token = response.data.results.token;
_this.$cookies.set('token',token,24 * 60 * 60);
let username = response.data.results.username;
_this.$cookies.set('username',username,24 * 60 * 60);
_this.$message({
message:'登录成功',
duration:1000,
onClose(){
// 保存登录状态
sessionStorage.token = token;
sessionStorage.username = response.data.results.username;
sessionStorage.mobile = response.data.results.mobile;
// 跳转主页
_this.$router.push('/')
}
});
# 通过get token 的方式查看是否登录
this.is_login = this.$cookies.get('token');