JWT
- 什么是JWT??
- JWT是指
一般用于用户认证,常用有(api,小程序,前后端分离)的项目json web token
- JWT是指
- jwt 原理请求图
JWT原理与使用 - 基于传统的token认证
- 用户登录,服务端返回token给用户,并保存token。
- 当用户再次访问时,携带token发起请求,服务端,查询数据库,对比token,token正确认证通过
- 基于JWT token认证
- 用户登录,服务端返回token(服务端不保存)给用户。
- 当用户再次访问时,携带token发起请求,服务端拿到token后,再做token检验。
- 优势:相比于传统,它token不用保存,减小数据库的查询,减小服务器的压力。
JWT 实现过程
用户登录成功,使用 jwt
创建一个 token
并返回给用户
jwt
token
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
注意:jwt 生成的token是由三段字符串组成的,并由
.
连接而成的
- 第一段字符串,
,内部包含算法和token类型。HEADER
{
“alg”: “HS256”,
“typ”: “JWT”
}
通过json转化成字符串,然后通过
base64url
加密而成
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
- 第二段字符串,
,内部是自定义值PAYLOAD
{
“phone”: “1234567890”,
“name”: “name”,
“exp”: “12” # 超时时间
}
通过json转化成字符串,然后通过
base64url
加密而成
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
- 第三段字符串:
- 第一步:把第一、第二段密文拼接起来
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
- 第二步:把第一步拼接起来的密文进行
加密HS256 + 加盐
- 第三步:对
加密后的密文,再进行HS256
加密base64url
- 第一步:把第一、第二段密文拼接起来
当用户再次访问时,需要携带token,后端需要进行token检验
- 获取token
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5ceyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
- 第一步:切割token
- 第二步:对第二段密文进行
解密,并获取base64url
信息检测token是否已经失效payload
{
“phone”: “1234567890”,
“name”: “name”,
“exp”: “12” # 超时时间
}
- 第三步:把第一、第二段密文拼接起来,进行
加密HS256 + 加盐
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
密文 =base64url
解密(用户带来的token中的第三段:SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c)
如果相等,则说明token未被修改过,认证通过。
Python 实现过程
-
pip install pyjwt
import jwt
import datetime
from jwt import exceptions
# 盐值
SALT = safa
def create_token():
# 构造header
headers = {
'typ': 'jwt',
'alg': 'HS256'
}
# 构造payload
payload = {
'user_id': 1, # 自定义用户ID
'username': 'name', # 自定义用户名
'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=5) # 超时时间
}
result = jwt.encode(payload=payload, key=SALT, algorithm="HS256", headers=headers).decode('utf-8')
return result
def get_payload(token):
"""
根据token获取payload
:param token:
:return:
"""
try:
verified_payload = jwt.decode(token, SALT, True)
return verified_payload
except exceptions.ExpiredSignatureError:
print('token已失效')
except jwt.DecodeError:
print('token认证失败')
except jwt.InvalidTokenError:
print('非法的token')
if __name__ == '__main__':
# jwt 生成token
token = create_token()
# jwt 检验token
payload = get_payload(token)