JWT原理與使用

JWT

  • 什麼是JWT??

    • JWT是指 json web token 一般用於用戶認證,常用有(api,小程序,前後端分離)的項目
  • 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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章