jwt原理,jwt开发流程,drf-jwt快速使用,drf-jwt定制返回格式,drf-jwt自定义用户表签发,drf-jwt自定义认证类,drf-jwt的签发源码分析,z
jwt原理:


JWT就是一段字符串,由三段信息构成的,将这三段信息文本用.链接一起就构成了Jwt字符串
1 header jwt的头部承载两部分信息:
声明类型,这里是jwt
声明加密的算法 通常直接使用 HMAC SHA256
公司信息
{
'typ': 'JWT',
'alg': 'HS256'
}
然后将头部进行base64编码,构成了第一部分.
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
2 payload 载荷就是存放有效信息的地方。
当前用户信息,用户名,用户id
exp: jwt的过期时间,这个过期时间必须要大于签发时间
定义一个payload:
{
"exp": "1234567890",
"name": "John Doe",
"user_id":99
}
然后将其进行base64编码,得到JWT的第二部分。
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
3. signature JWT的第三部分是一个签证信息,这个签证信息由三部分组成:
header (base64后的)
payload (base64后的)
secret
这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。
将这三部分用.连接成一个完整的字符串,构成了最终的jwt:
使用jwt认证的开发流程,就是两部分
-第一部分:签发token的过程,登录做的
-用户携带用户名和密码,访问我,我们校验通过,生成token串,返回给前端
-第二部分:token认证过程,登录认证时使用,其实就是咱们之前讲的认证类,在认证类中完成对token的认证操作
-用户访问我们需要登陆后才能访问的接口,必须携带我们签发的token串(请求头)
-我们取出token,验证该token是否过期,是否被篡改,是否是伪造的
-如果正常,说明荷载中的数据,就是安全的,可以根据荷载中的用户id,查询出当前登录用户,放到request中即可
安装:pip3 install djangorestframework-jwt
快速使用:
-签发过程(快速签发),必须是auth的user表(人家帮你写好了)
-登录接口--》基于auth的user表签发的
-认证过程
-登录认证,认证类(写好了)
url内:

view内:

前端:

总结:
-签发:只需要在路由中配置
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
path('login/', obtain_jwt_token),
]
-认证:视图类上加
class BookView(APIView):
authentication_classes = [JSONWebTokenAuthentication] # 认证类,drf-jwt提供的
permission_classes = [IsAuthenticated] # 权限类,drf提供的
-访问的时候,要在请求头中携带,必须叫
Authorization:
jwt token串
drf-jwt定制返回格式:
登录签发token的接口,要返回code,msg,username,token等信息
写一个py文件:
def common_sponse(token,user=None,request=None):
return {
'code':100,
'msg':'登陆成功',
'username':user.username,
'token':token,
}
setting中配置:
JWT_AUTH = {
'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.s.common_sponse', #app01.s.common_sponse为写的py文件路径
}
from rest_framework_jwt.settings import api_settings
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
class UserView(ViewSet):
def login(self, request):
username = request.data.get('username')
password = request.data.get('password')
user = User.objects.filter(username=username, password=password).first()
print(user)
if user:
# 登录成功,签发token
# 通过user获取payload
payload = jwt_payload_handler(user)
print(payload)
# 通过payload获取token
token = jwt_encode_handler(payload)
return Response({'code': 100, 'msg': '登陆成功', 'username': user.username, 'token': token})
else:
return Response({'code': 101, 'msg': '用户名或密码错误'})
url内:
urlpatterns = [
path('login/', UserView.as_view({'post': 'login'}))
]
drf-jwt自定义认证类:
序列化类中:
import jwt
from rest_framework.authentication import BaseAuthentication
from rest_framework_jwt.settings import api_settings
jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
from app01.models import User
from rest_framework.exceptions import AuthenticationFailed
class JWTAuthentication(BaseAuthentication):
def authenticate(self, request):
token = request.META.get('HTTP_TOKEN')
try:
payload = jwt_decode_handler(token)
user_id = payload.get('user_id')
user = User.objects.get(pk=user_id)
except jwt.ExpiredSignature:
raise AuthenticationFailed('token过期')
except jwt.DecodeError:
raise AuthenticationFailed('解码失败')
except jwt.InvalidTokenError:
raise AuthenticationFailed('token认证异常')
except Exception:
raise AuthenticationFailed('token认证异常')
return user, token
view中:
from app01.auth import JWTAuthentication
class BookView(APIView):
authentication_classes = [JWTAuthentication]
def get(self, request):
return Response('看见人了')

浙公网安备 33010602011771号