天天看点

JWT原理与使用

JWT

  • 什么是JWT??
    • JWT是指

      json web token

      一般用于用户认证,常用有(api,小程序,前后端分离)的项目
  • jwt 原理请求图
    JWT原理与使用
  • 基于传统的token认证
    • 用户登录,服务端返回token给用户,并保存token。
    • 当用户再次访问时,携带token发起请求,服务端,查询数据库,对比token,token正确认证通过
  • 基于JWT token认证
    • 用户登录,服务端返回token(服务端不保存)给用户。
    • 当用户再次访问时,携带token发起请求,服务端拿到token后,再做token检验。
    • 优势:相比于传统,它token不用保存,减小数据库的查询,减小服务器的压力。

JWT 实现过程

用户登录成功,使用

jwt

创建一个

token

并返回给用户
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

注意:jwt 生成的token是由三段字符串组成的,并由

.

连接而成的

  • 第一段字符串,

    HEADER

    ,内部包含算法和token类型。

{

“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.

    eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

    .SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
  • 第一步:切割token
  • 第二步:对第二段密文进行

    base64url

    解密,并获取

    payload

    信息检测token是否已经失效

    {

    “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)