JWT——json web token

JWT

jwt=Json Web token

1)jwt分三段式:头.体.签名 (head.payload.sgin)
2)头和体是可逆加密,让服务器可以反解出user对象;签名是不可逆加密,保证整个token的安全性的
3)头体签名三部分,都是采用json格式的字符串,进行加密,可逆加密一般采用base64算法,不可逆加密一般采用hash(md5)算法

头中的内容是基本信息:公司信息、项目组信息、token采用的加密方式信息

体中的内容是关键信息:用户主键、用户名、签发时客户端信息(设备号、地址)、过期时间

签名中的内容是安全信息:头的加密结果 + 体的加密结果 + 服务器不对外公开的安全码 进行md5加密


基于jwt校验

将token按 . 拆分为三段字符串:
1)第一段 头加密字符串 一般不需要做任何处理
2)第二段 体加密字符串,要反解出用户主键,通过主键从User表中就能得到登录用户,过期时间和设备信息都是安全信息,确保token没过期,且时同一设备来的
3)再用 第一段 + 第二段 + 服务器安全码 不可逆md5加密,与第三段 签名字符串 进行碰撞校验,通过后才能代表第二段校验得到的user对象就是合法的登录用户

drf项目的jwt认证开发流程(重点)

1)登录接口逻辑中签发token,返回给客户端,存到cookies中

2)在认证类中,校验token,所有视图类请求,请求有token,就会反解出user对象,在视图类中用request.user就能访问登录的用户

注:登录接口需要做 认证 + 权限 两个局部禁用


安装pip install djangorestframework-jwt


    from rest_framework_jwt.views import ObtainJSONWebToken,VerifyJSONWebToken,RefreshJSONWebToken,obtain_jwt_token
    path('login/', obtain_jwt_token), 

jwt的配置参数

import datetime
JWT_AUTH={
    'JWT_RESPONSE_PAYLOAD_HANDLER':'app02.utils.my_jwt_response_payload_handler',
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7), # 过期时间,手动配置
}

控制登录接口返回的数据格式

	-第一种方案,自己写登录接口
    
    -第二种写法,用内置,控制登录接口返回的数据格式
    	-jwt的配置信息中有这个属性
'JWT_RESPONSE_PAYLOAD_HANDLER':'rest_framework_jwt.utils.jwt_response_payload_handler',
    	-重写jwt_response_payload_handler,配置
        
   def jwt_response_payload_handler(token, user=None, request=None):
    return {
        'token': token
    }

自定义基于jwt的认证

from rest_framework.authentication import BaseAuthentication
from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
from rest_framework.exceptions import AuthenticationFailed
# from rest_framework_jwt.authentication import jwt_decode_handler
from rest_framework_jwt.utils import jwt_decode_handler # 跟上面是一个
import jwt

from api import models

class MyJwtAuthentication(BaseAuthentication):
    def authenticate(self, request):
        jwt_value=request.META.get('HTTP_AUTHORIZATION')
        if jwt_value:
            try:
                payload=jwt_decode_handler(jwt_value)
            except Exception as e:
                raise AuthenticationFailed(str(e))
            # 第一种,去数据库查
            user=models.User.objects.get(pk=payload.get('user_id'))
             # 第二种不查库
            user=models.User(id=payload.get('user_id'),username=payload.get('username'))
            return user,jwt_value
        raise AuthenticationFailed('您没有携带认证信息')


class MyJwtAuthentication(BaseJSONWebTokenAuthentication):
    def authenticate(self, request):
        jwt_value=request.META.get('HTTP_AUTHORIZATION')
        if jwt_value:
            try:
                payload=jwt_decode_handler(jwt_value)
            except Exception as e:
                raise AuthenticationFailed(str(e))
            user=self.authenticate_credentials(payload)
            return user,jwt_value
        raise AuthenticationFailed('您没有携带认证信息')

猜你喜欢

转载自www.cnblogs.com/pythonwl/p/13368475.html