JWT token签发
jwt模块
包名: rest_framework_jwt
安装: pip install djangorestframework-jwt
from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
payload = jwt_payload_handler(obj)
token = jwt_encode_handler(payload)
通过这两个方法去签发token
jwt完成token签发,实现多方式登录
from rest_framework import serializers
from api import models
from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
import re
class LoginModelSerializer(serializers.ModelSerializer):
username = serializers.CharField(write_only=True)
password = serializers.CharField(write_only=True)
class Meta:
model = models.User
fields = ('username', 'password')
def validate(self, attrs):
- 校验用户是否存在, 存在就给token
user = self._get_user(attrs)
- Token的处理
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
self.user = user
self.token = token
return attrs
def _get_user(self, attrs):
username = attrs.get('username')
password = attrs.get('password')
- 使用re模块匹配正则
- 前端传递过来的一定是一个username接收的, 所有可以通过正则匹配到底是邮箱电话号码还是用户名
if re.match(r'[\w]+(\.[\w]+)*@[\w]+(\.[\w])+', username):
print('邮箱')
user = models.User.objects.filter(email=username).first()
elif re.match(r'^1[3-9][0-9]{9}$', username):
print('号码')
user = models.User.objects.filter(tel=username).first()
else:
print('账号')
user = models.User.objects.filter(username=username).first()
if not user:
raise serializers.ValidationError({'username': '用户信息错误'})
if not user.check_password(password):
raise serializers.ValidationError({'password': '密码有误'})
return user
import datetime
JWT_AUTH = {
- 配置token过期时间
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),
- 配置请求的authorization的前缀
'JWT_AUTH_HEADER_PREFIX': 'TOKEN',
- 可以“刷新”未过期的令牌以获得具有更新到期时间的全新令牌
'JWT_ALLOW_REFRESH': True,
- 只能将刷新令牌保留至JWT_REFRESH_EXPIRATION_DELTA
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
}
jwt有三个方法
-
token的签发
-
刷新token
-
验证token
JWT作用在于生成Token给前端保存, 后端只保存算法,不是像之前的Auth模块一样,在数据库中保存数据, 减少了数据的IO,减小服务器的压力
JWT组成部分
- 头(Base64可逆算法)
- 载荷(Base64可逆算法)
- 签名(碰撞解密,hashlib模块,hs256算法)