# 视频截图
视频来源
类似于中间件的功能,在执行视图函数之前先执行这个认证的功能。
验证类中有三种返回值
上面的 None 就是什么都不干
登录页面不用认证
jwt 官网
问题:
在生成 token 的时候需要用到用户名和密码这些前端返回的表单数据么?
# 代码如下
当前的官网
from django.test import TestCase | |
import os | |
import django | |
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drfdemo.settings') | |
django.setup() | |
from lyb.views import LybViewSet | |
from rest_framework import routers | |
from drfdemo import urls | |
from lyb.models import Lyb, MyUsers | |
import jwt | |
import datetime | |
if __name__ == '__main__': | |
key = 'secretdfjsdf' # 自定义的值 | |
algorithm = "HS256" | |
payload = { | |
'id': 2, | |
"name": "jack" | |
} | |
token = jwt.encode(payload=payload, key=key, algorithm=algorithm) | |
print(token) | |
res = jwt.decode(token, key=key, algorithms=algorithm) | |
print(res) | |
''' | |
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MiwibmFtZSI6ImphY2sifQ.esdckJSoFhqS23tbhKNOaCrh0Gm3a0z1uCPSivTCtUc | |
{'id': 2, 'name': 'jack'} | |
''' |
# PyJWT 使用
# 使用 HS256 编码和解码令牌
import jwt | |
key = "secret" # 此字段可以修改成自定义的字符串 | |
encoded = jwt.encode({"some": "payload"}, key, algorithm="HS256") | |
print(encoded) | |
jwt.decode(encoded, key, algorithms="HS256") | |
''' | |
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzb21lIjoicGF5bG9hZCJ9.Joh1R2dYzkRvDkqv3sygm5YyK8Gi4ShZqbhK2gxcs2U | |
{'some': 'payload'} | |
''' |
# 指定其他标头
token = jwt.encode( | |
{"some": "payload"}, | |
"secret", | |
algorithm="HS256", | |
headers={"kid": "230498151c214b788dd97f22b85410a5"}, | |
) | |
print(token) | |
print(jwt.decode(token, 'secret', "HS256")) # 这里并没有解码出 headers 中的信息 | |
""" | |
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjIzMDQ5ODE1MWMyMTRiNzg4ZGQ5N2YyMmI4NTQxMGE1In0.eyJzb21lIjoicGF5bG9hZCJ9.gdQ884yjlnLnIrYjfQaClE6rJC2x8v2OP2s_eXOLhZA | |
{'some': 'payload'} | |
""" |
# 未经验证即可读取标头
这里的标头即上面的 headers
某些 API 要求您在未经验证的情况下读取 JWT 标头。例如,在令牌颁发者使用多个密钥的情况下,您无法事先知道颁发者的哪个公钥或共享机密用于验证,则颁发者可能会在标头中包含密钥的标识符。
jwt.get_unverified_header(encoded) | |
# {'alg': 'RS256', 'typ': 'JWT', 'kid': 'key-id-12345...'} |
# Registered Claim Names
JWT 规范定义了一些已注册的声明名称,并定义了应如何使用它们。PyJWT 支持以下注册声明名称:
- “exp” (Expiration Time) Claim
- “nbf” (Not Before Time) Claim
- “iss” (Issuer) Claim
- “aud” (Audience) Claim
- “iat” (Issued At) Claim
# Expiration Time Claim (exp) 到期时间声明
“exp”(到期时间)声明标识了到期时间,此时或之后不得接受 JWT 进行处理。处理 “exp” 索赔要求当前日期 / 时间必须早于 “exp” 索赔中列出的到期日期 / 时间。实现者可以提供一些小的回旋余地,通常不超过几分钟,以考虑时钟偏差。其值必须是包含 “数字日期” 值的数字。此声明的使用是可选的。
您可以将过期时间作为 UTC UNIX 时间戳(整数)或日期时间传递,后者将转换为整数。例如:
from datetime import timezone | |
from datetime import datetime | |
jwt.encode({"exp": 1371720939}, "secret") | |
jwt.encode({"exp": datetime.now(tz=timezone.utc)}, "secret") |
过期时间在 jwt.decode()
中自动验证并引发 jwt.ExpiredSignatureError
。过期签名如果过期时间是过去,则为错误:
try: | |
jwt.decode("JWT_STRING", "secret", algorithms=["HS256"]) | |
except jwt.ExpiredSignatureError: | |
# Signature has expired | |
... |
过期时间将与当前 UTC 时间进行比较(由时间 timegm(datetime.now(tz=timezone.utc).utctimetuple())
给出),因此请确保在编码中使用 UTC 时间戳或日期时间。
您可以使用 options 参数中的 verify_exp
参数关闭过期时间验证。
PyJWT 还支持过期时间定义的回旋余地部分,这意味着您可以验证过去但不是很远的过期时间。例如,如果您有一个 JWT 有效负载,其过期时间设置为创建后 30 秒,但您知道有时您将在 30 秒后处理它,则可以设置 10 秒的回旋余地以获得一些余量:
jwt_payload = jwt.encode( | |
{"exp": datetime.now(tz=timezone.utc) + datetime.timedelta(seconds=30)}, | |
"secret", | |
) | |
time.sleep(32) | |
# JWT payload is now expired | |
# But with some leeway, it will still validate | |
jwt.decode(jwt_payload, "secret", leeway=10, algorithms=["HS256"]) |
可以使用 datetime.timedelta 实例,而不是将 leeway 指定为秒数。上面示例中的最后一行等效于
jwt.decode( | |
jwt_payload, "secret", leeway=datetime.timedelta(seconds=10), algorithms=["HS256"] | |
) |
目前尝试时, leeway
参数已经不能使用了
pay_load = { | |
'id': 1, | |
'name': 'jack' | |
} | |
import datetime | |
jwt_payload = jwt.encode( | |
{"exp": datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(seconds=2), "id": 1, "name": 'jack'}, | |
"secret", | |
) | |
import time | |
time.sleep(3) | |
print(jwt_payload) | |
try: | |
print(jwt.decode(jwt_payload, 'secret', algorithms="HS256")) | |
except jwt.ExpiredSignatureError: | |
print("token过期了") | |
''' | |
如果没有过期,则输出: | |
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2NjMzMTM5ODEsImlkIjoxLCJuYW1lIjoiamFjayJ9.Jb2KPgFvHTskacJcXPxb3bH_3xKxLq126z5v6_-dl9E | |
{'exp': 1663313981, 'id': 1, 'name': 'jack'} | |
''' |