jwt(json web token)

Python之jwt(json web token)

一、什么是jwt

在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证。我们不再使用Session认证机制,而使用Json Web Token(本质就是token)认证机制。

jwt全称json web token,是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准
((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。
JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务
器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认
证,也可被加密。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LJqSn4jc-1636029379226)(007S8ZIlgy1ggprivsr69j31i50u0tao.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aESAO1IM-1636029379228)(007S8ZIlgy1ggpriyyay5j31i80u03zl.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HvqAz1fJ-1636029379229)(007S8ZIlgy1ggprj27cflj31fq0u0abx.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MincRGuj-1636029379231)(007S8ZIlgy1ggprj5moolj31ob0u0q4w.jpg)]

二、jwt构成和工作原理

1、jwt的构成

jwt信息就是一段字符串,有三段信息组成,将这三段信息当文本用,连接在一起就构成了jwt字符串

例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

三部分均由.分割开来

第一部分叫头部(header),第二部分叫载荷(payload),第三部分叫签证(signatrue)

header

jwt的头部承载两部分信息:

  • 声明类型:这是jwt
  • 声明加密的算法:通常直接使用HMAC SHA256

完整的头部如下

{
   
  'typ': 'JWT',
  'alg': 'HS256'
}
payload

载荷就是存放有效信息的地方,这些有效信息包含三个部分:

  • 标准中注册的声明
  • 公共的声明
  • 私有的声明

标准中注册的声明 (建议但不强制使用):

  • iss: jwt签发者
  • sub: jwt所面向的用户
  • aud: 接收jwt的一方
  • exp: jwt的过期时间,这个过期时间必须要大于签发时间
  • nbf: 定义在什么时间之前,该jwt都是不可用的.
  • iat: jwt的签发时间
  • jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避时序攻击。

公共的声明 : 公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.

私有的声明 : 私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息

定义一个payload:

{
   
    "user_id":456,
    "username":"zhang",
    "admin":true
}

将其用base64编码:

eyJ1c2VyX2lkIjogNDU2LCAidXNlcm5hbWUiOiAiemhhbmciLCAiYWRtaW4iOiB0cnVlfQ==
signature

JWT的第三部分是一个签证信息,这个签证信息由三部分组成:

  • header (base64后的)
  • payload (base64后的)
  • secret

注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。

关于签发和核验JWT,我们可以使用Django REST framework JWT扩展来完成。

2、工作原理
签发

根据登录请求提交来的 账号 + 密码 + 设备信息 签发 token

"""
1)用基本信息存储json字典,采用base64算法加密得到 头字符串
2)用关键信息存储json字典,采用base64算法加密得到 体字符串
3)用头、体加密字符串再加安全码信息存储json字典,采用hash md5算法加密得到 签名字符串

账号密码就能根据User表得到user对象,形成的三段字符串用 . 拼接成token返回给前台
"""
校验

根据客户端带token的请求 反解出 user 对象

"""
1)将token按 . 拆分为三段字符串,第一段 头加密字符串 一般不需要做任何处理
2)第二段 体加密字符串,要反解出用户主键,通过主键从User表中就能得到登录用户,过期时间和设备信息都是安全信息,确保token没过期,且时同一设备来的
3)再用 第一段 + 第二段 + 服务器安全码 不可逆md5加密,与第三段 签名字符串 进行碰撞校验,通过后才能代表第二段校验得到的user对象就是合法的登录用户
"""
drf项目的jwt认证开发流程(重点)
"""
1)用账号密码访问登录接口,登录接口逻辑中调用 签发token 算法,得到token,返回给客户端,客户端自己存到cookies中

2)校验token的算法应该写在认证类中(在认证类中调用),全局配置给认证组件,所有视图类请求,都会进行认证校验,所以请求带了token,就会反解出user对象,在视图类中用request.user就能访问登录的用户

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

三、drf-jwt的安装和使用

安装
pip install djangorestframework-jwt

# 还有一个
djangorestframework-simplejwt
使用

签发:

# 1 创建超级用户
python3 manage.py createsuperuser
# 2 配置路由urls.py
from django.urls import path
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
    path('login/', obtain_jwt_token),
]
# 3 postman测试
向后端接口发送post请求,携带用户名密码,即可看到生成的token

# 4 setting.py中配置认证使用jwt提供的jsonwebtoken
# 5 postman发送访问请求(必须带jwt空格)

认证:

from rest_framework_jwt.authentication import JSONWebTokenAuthentication  # drf_jwt内置的认证类
from rest_framework.permissions import IsAuthenticated 
class BookView(APIView):
    # 使用drf_jwt内置的认证,必须加这两个
    authentication_classes = [JSONWebTokenAuthentication, ]
    permission_classes = [IsAuthenticated]

四、drf-jwt源码解析

1、obtain_jwt_token源码解析
from django.contrib import admin
from django.urls import path
from app01 import views
from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', views.BookAPIView.as_view())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的基于 JSON Web TokenJWT)的身份验证案例: 1. 安装所需的库 ``` pip install pyjwt ``` 2. 生成JWT Token ```python import jwt import datetime # 定义过期时间 expire_time = datetime.datetime.utcnow() + datetime.timedelta(minutes=30) # 定义payload payload = { 'user_id': '123456', 'username': 'john', 'exp': expire_time } # 生成token jwt_token = jwt.encode(payload, 'secret_key', algorithm='HS256') print(jwt_token) ``` 上述代码中,我们使用了 pyjwt 库来生成 JWT Token。它的 encode() 方法接收三个参数:payload、密钥和算法。payload 是一个字典,包含我们想要在 Token 中存储的信息,例如用户ID、用户名、过期时间等等。密钥是一个字符串,用于加密 Token。算法是指用于加密 Token 的算法,这里我们选择了 HS256。 3. 验证JWT Token ```python import jwt # 定义Token jwt_token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMTIzNDU2IiwidXNlcm5hbWUiOiJqb2huIiwiZXhwIjoxNjMxMzEwMDUzfQ.XsDEjcd7jH8qC-6pZlWjZaFvDz-pT8NvQYrWb8I3-5c' # 验证Token try: decoded_token = jwt.decode(jwt_token, 'secret_key', algorithms=['HS256']) print(decoded_token) except jwt.ExpiredSignatureError: print('Token已过期') except jwt.InvalidTokenError: print('无效的Token') ``` 上述代码中,我们使用了 pyjwt 库的 decode() 方法来验证 Token。它接收三个参数:Token、密钥和算法。如果 Token 有效,则返回包含信息的字典。如果 Token 过期或无效,则会引发 jwt.ExpiredSignatureError 或 jwt.InvalidTokenError 异常。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值