jwt json web token

  签发----登录成功后签发
  认证---需要登录才能访问的接口,通过认证才能继续操作

2 原理-----jwt和session,cookie区别

2.1cookies

2.2 session

image

2.2.1sessionmiddleware

2.3 jwt

image

tooken长什么样?
三段式,用.分割
每段b64编码
	1st段:公司信息, 加密方式 就是jwt,一般固定
	2nd段:荷载payload :一般放:登录用户信息(如用户名,用户id,过期时间。签发时间,是否超级用户)
	3rd段:签名singature二进制数据
		签发阶段:by头部和荷载使用某种加密方式get
		校验阶段:拿到token,取出第1、2部分,通过之前同样的加密方式得到新签名,
				比较:	一样	信任
					不同	危险
jwt实现了不在后端存储,但安全

3jwt开发重点,签发(登录接口),校验(认证类逻辑)

4.simple_jwt使用(djangorestframework_simplejwt)

django:simple_jwt, django-rest-framework-jwt(不用了,老)
flask:flask-jwt-extend
	登陆签发:默认使用auth的user表--》创建个用户--》能登录了
    	路由:   登陆接口了 
        path('login/', token_obtain_pair), 
        # 127.0.0.1:8080/app01/login-->post--》用户名密码就能登陆
    - 认证
    class UserTokenView(GenericViewSet, mixins.CreateModelMixin):
        # 必须登陆后才能新增
        authentication_classes = [JWTAuthentication]
        permission_classes = [IsAuthenticated]

5.simple_jwt配置文件

要在app注册,不然不做国际化


登录后,返回两token
	1:refresh
	2:access(用这个)

image
exp过期时间,iat签发时间
exp-iat=过期时长(单位秒)

5.1.1simple_jwt配置文件(源码有)

默认配置文件

# JWT配置
SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),  # Access Token的有效期
    'REFRESH_TOKEN_LIFETIME': timedelta(days=7),  # Refresh Token的有效期
    
    # 对于大部分情况,设置以上两项就可以了,以下为默认配置项目,可根据需要进行调整
    
    # 是否自动刷新Refresh Token
    'ROTATE_REFRESH_TOKENS': False,  
    # 刷新Refresh Token时是否将旧Token加入黑名单,如果设置为False,则旧的刷新令牌仍然可以用于获取新的访问令牌。需要将'rest_framework_simplejwt.token_blacklist'加入到'INSTALLED_APPS'的配置中
    'BLACKLIST_AFTER_ROTATION': False,  
    'ALGORITHM': 'HS256',  # 加密算法
    'SIGNING_KEY': settings.SECRET_KEY,  # 签名密匙,这里使用Django的SECRET_KEY
    # 如为True,则在每次使用访问令牌进行身份验证时,更新用户最后登录时间
    "UPDATE_LAST_LOGIN": False, 
    # 用于验证JWT签名的密钥返回的内容。可以是字符串形式的密钥,也可以是一个字典。
    "VERIFYING_KEY": "",
    "AUDIENCE": None,# JWT中的"Audience"声明,用于指定该JWT的预期接收者。
    "ISSUER": None, # JWT中的"Issuer"声明,用于指定该JWT的发行者。
    "JSON_ENCODER": None, # 用于序列化JWT负载的JSON编码器。默认为Django的JSON编码器。
    "JWK_URL": None, # 包含公钥的URL,用于验证JWT签名。
    "LEEWAY": 0, # 允许的时钟偏差量,以秒为单位。用于在验证JWT的过期时间和生效时间时考虑时钟偏差。
    # 用于指定JWT在HTTP请求头中使用的身份验证方案。默认为"Bearer"
    "AUTH_HEADER_TYPES": ("Bearer",), 
    # 包含JWT的HTTP请求头的名称。默认为"HTTP_AUTHORIZATION"
    "AUTH_HEADER_NAME": "HTTP_AUTHORIZATION", 
     # 用户模型中用作用户ID的字段。默认为"id"。
    "USER_ID_FIELD": "id",
     # JWT负载中包含用户ID的声明。默认为"user_id"。
    "USER_ID_CLAIM": "user_id",
    
    # 用于指定用户身份验证规则的函数或方法。默认使用Django的默认身份验证方法进行身份验证。
    "USER_AUTHENTICATION_RULE": "rest_framework_simplejwt.authentication.default_user_authentication_rule",
    #  用于指定可以使用的令牌类。默认为"rest_framework_simplejwt.tokens.AccessToken"。
    "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",),
    # JWT负载中包含令牌类型的声明。默认为"token_type"。
    "TOKEN_TYPE_CLAIM": "token_type",
    # 用于指定可以使用的用户模型类。默认为"rest_framework_simplejwt.models.TokenUser"。
    "TOKEN_USER_CLASS": "rest_framework_simplejwt.models.TokenUser",
    # JWT负载中包含JWT ID的声明。默认为"jti"。
    "JTI_CLAIM": "jti",
    # 在使用滑动令牌时,JWT负载中包含刷新令牌过期时间的声明。默认为"refresh_exp"。
    "SLIDING_TOKEN_REFRESH_EXP_CLAIM": "refresh_exp",
    # 滑动令牌的生命周期。默认为5分钟。
    "SLIDING_TOKEN_LIFETIME": timedelta(minutes=5),
    # 滑动令牌可以用于刷新的时间段。默认为1天。
    "SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1),
    # 用于生成access和刷refresh的序列化器。
    "TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer",
    # 用于刷新访问令牌的序列化器。默认
    "TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSerializer",
    # 用于验证令牌的序列化器。
    "TOKEN_VERIFY_SERIALIZER": "rest_framework_simplejwt.serializers.TokenVerifySerializer",
    # 用于列出或撤销已失效JWT的序列化器。
    "TOKEN_BLACKLIST_SERIALIZER": "rest_framework_simplejwt.serializers.TokenBlacklistSerializer",
    # 用于生成滑动令牌的序列化器。
    "SLIDING_TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainSlidingSerializer",
    # 用于刷新滑动令牌的序列化器。
    "SLIDING_TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer",
}

###5.1.2simple_jwt在项目中配置(参考rest-framework)
from datetime import timedelta
SIMPLE_JWT ={
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),  # Access Token的有效期
    'REFRESH_TOKEN_LIFETIME': timedelta(days=7),  # Refresh Token的有效期
    "AUTH_HEADER_TYPES": ("TOKEN",),
}

6定制登录后的返回格式

原来返回

原来使用
image

6.1自己写个序列化类

settings.py的最后一行
image
'TOKEN_OBTAIN_SERIALIZER':'app01.serializer.CommonTokenObtainSerializer'
serialier.py

{
    "code": 100,
    "msg": "登录成功",
    "username": "lqz",
    "refresh": "",
    "access": ""
}

前端看到

{
    "code": 100,
    "msg": "登录成功",
    "username": "lqz",
    "refresh": "",
    "access": ""
}

也可以把user信息放到荷载里面
image
对荷载b64解码就能看到自己加进去的username,这样,就不需要在自己定制的返回格式里面加

补充base64

  • (长度一定是4的倍数,如果不是,用等号补齐,后面最多3个等号)

      是编码方式,不是加密
      作用
      1.网络传输----字符串编码成base64
      2.图片用b64传给前端
      3.jwt使用
    

image

如果是b64图片,可以这么保存,解码出来是bytes格式,可以直接写入到文件,wb模式

image

posted @ 2024-04-18 15:33  沉岩  阅读(2)  评论(0编辑  收藏  举报