Un article pour comprendre Token (JWT) [code python]

1. Découvrez Token pour la première fois

Permettez-moi de parler de ce qu'est un token. Le token ici fait référence à JWT (Json Web Token) par défaut.

Découvrez Json Web Token

Générer JWT en ligne

type de jeton

Jeton traditionnel

Le jeton traditionnel est qu'après la connexion d'un utilisateur, le serveur renvoie un jeton à l'utilisateur pour qu'il l'enregistre. Ce jeton peut être une combinaison de plusieurs lettres aléatoires et le serveur conserve le même jeton (par exemple, en utilisant redis pour stocker le jeton)

Lorsque l'utilisateur accède à d'autres interfaces, il doit porter ce jeton, puis le serveur juge si le jeton existe dans redis pour juger si l'utilisateur s'est connecté ou a les autorisations correspondantes

JWT (jeton Web json)

Contrairement aux jetons traditionnels, les jetons Web json n'ont pas besoin d'être conservés sur le serveur.

Flux de traitement:

Une fois que l'utilisateur s'est connecté, le serveur calcule et renvoie un jeton chiffré selon certaines règles. Le jeton contient certaines informations nécessaires sur l'utilisateur, telles que l'identifiant de l'utilisateur et l'heure d'expiration du jeton.

Lorsque les utilisateurs accèdent à d'autres interfaces, ils doivent transporter ce jeton, puis le serveur vérifie ce jeton avec un mot de passe

  • Vérifiez que le jeton est le jeton envoyé par le serveur
  • Vérifier l'heure d'expiration du jeton

Une fois que tout est correct, l'utilisateur est considéré comme connecté et dispose des autorisations correspondantes

Où le jeton sera-t-il utilisé?

Dans notre développement avec séparation des frontaux et des back-ends, il est souvent nécessaire de fournir une authentification pour les services multi-end, tels que le mobile, le web et les petits programmes. Il y a des milliers d'utilisateurs et des milliers d'interfaces.

Et comment pouvons-nous nous assurer que chaque interface autorise uniquement les utilisateurs autorisés à y accéder? (Par exemple, seul l'administrateur peut accéder ou seul l'utilisateur connecté peut accéder)

La solution consiste à renvoyer un JWT à l'utilisateur, puis à juger à partir de ce jeton si l'utilisateur actuel de l'interface d'accès répond à nos paramètres

2. Caractéristiques de Json Web Token

avantage

  • Pas besoin de stocker les informations de statut de connexion de l'utilisateur sur le serveur (comme redis)
  • Le même jeton peut être utilisé dans différents serveurs, environnements et même différents services d'entreprise (tant que la clé est configurée)
  • Peut être utilisé sur mobile, Web, applet, etc.

Désavantage

Bien sûr, il y a des inconvénients

Par exemple, la génération et l'analyse du jeton prennent du temps. Par rapport aux méthodes traditionnelles de vérification des jetons, la génération et l'analyse JWT prendront plus de temps.

Par exemple, vous ne pouvez pas annuler un token existant (si le token est divulgué, même si l'utilisateur a changé le mot de passe pendant la période de validité du token, l'attaquant peut toujours utiliser le token comme il le souhaite)

3. Principe du jeton

Si vous êtes entré sur le site Web de génération de JWT en ligne , vous pouvez voir cette image

Le jeton Web Json contient trois parties, l'en-tête, les données et la signature

Structure JWT

tête

L'en-tête peut mettre des informations sur le jeton, telles que des informations sur l'algorithme de cryptage, l'heure à laquelle le jeton a été créé et l'heure d'expiration, puis utiliser base64 pour le cryptage

Remarque (les données chiffrées en base64 peuvent être déchiffrées par n'importe qui, ce qui équivaut à la transparence)

tel que

{
    
    
  "typ": "jwt", # token类型
  "iat": 1603426198, # 生成时间
  "exp": 1603426298 # 过期时间
}

Les données

Les données peuvent mettre un identifiant d'utilisateur, un niveau d'autorisation, etc., mais veuillez ne pas mettre de données secrètes, telles que (mot de passe de l'utilisateur, nom réel de l'utilisateur)

Remarque (car tout le monde peut déchiffrer l'en-tête et les données en utilisant base64)

{
    
    
  "say": "我爱你",
  "from": "音宫",
  "to": "小姐姐",
  "uid": 1,
  "role": "admin"
}

Signature

La partie signature est l'essence même du JWT. Les deux chaînes d'en-tête et de données sont hachées et chiffrées. Ce hachage est différent du chiffrement base64. Le chiffrement par hachage nécessite un mot de passe, qui ne peut pas être divulgué à l'utilisateur. , Autrement dit, le contenu chiffré est irréversible

Par exemple, la méthode de cryptage est la suivante

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

Qu'est-ce que ça veut dire?

Par exemple, la partie en-tête enregistre la création à 7 heures et l'expiration à 8 heures, ce qui signifie que la période de validité est d'une heure.

La partie de données enregistre l'ID d'un certain utilisateur.

À ce stade, une fois le serveur crypté avec un mot de passe, une chaîne de chaînes sera formée (tant que les données dans l'en-tête et les parties de données ne sont pas modifiées, la même chaîne sera formée à chaque fois que le cryptage est effectué)

Vous pouvez accéder à l'interface de service entre 7 et 8 heures et peut être utilisé normalement

Cependant , à 9 heures, le pirate a trouvé votre jeton, mais le jeton a expiré, puis le pirate a modifié l'heure d'expiration de l'en-tête, puis a utilisé ce jeton pour accéder à l'interface de service

À ce moment, il y aura une erreur, pourquoi?

Parce qu'après la modification des informations d'en-tête, la signature changera, mais le pirate n'a pas généré le mot de passe du jeton et le pirate ne peut pas construire la signature correcte.

Lorsque le jeton est vérifié en arrière-plan, l'en-tête et la partie données seront cryptés avec un mot de passe pour générer une signature, puis comparés avec le jeton soumis pour voir s'il est cohérent

4. Générer un jeton

Python est utilisé ici pour démontrer la génération de jeton

Nous devons d'abord importer plusieurs packages

import time
import json
import base64
import hashlib
import hmac

Ce sont des outils permettant d'obtenir l'heure actuelle, de générer et d'analyser le format json et de chiffrer

Préparez deux paramètres à l'avance

exp=60 # token有效期 秒

salt="xxx" # 加密的密码 不能让用户知道

En-tête de traitement

    headers = {
    
    
        "typ": "ygt",
        "exp": int(time.time() + exp)  # 过期时间戳
    }

En-tête chiffré

first = base64.urlsafe_b64encode(json.dumps(headers, separators=(',', ':')).encode('utf-8').replace(b'=', b'')).decode(
    'utf-8').replace('=', '')

Traitement de la charge utile des données

La charge utile stocke ici certaines données utilisateur (uid, rôle, etc.) Remarque: ne mettez pas de données privées ici (comme les mots de passe utilisateur, etc.)

payload = {
    
    
  "uid": 1,
  "author": "好音宫",
  "admin": 1
}

Charge utile chiffrée

second = base64.urlsafe_b64encode(json.dumps(payload, separators=(',', ':')).encode('utf-8').replace(b'=', b'')).decode(
    'utf-8').replace('=', '')

Signature cryptographique

La troisième partie est la signature, la signature doit utiliser du sel, qui est le mot de passe crypté

Après avoir épissé les deux premières parties, utilisez le cryptage par hachage pour crypter les deux parties de la signature pour obtenir une chaîne, appelée signature

# 拼接前两部分
first_second = f"{first}.{second}"

# 对前面两部分签名呀
third = base64.urlsafe_b64encode(
    hmac.new(salt.encode('utf-8'), first_second.encode('utf-8'), hashlib.sha256).digest()).decode('utf-8').replace('=',
                                                                                                                   '')

# 拼接签名和前两部分,就叫做token啦
token = ".".join([first, second, third])
print(token)

Accédez au site officiel pour analyser les informations du jeton

Imprimez notre token, copiez le token

eyJ0eXAiOiJ5Z3QiLCJleHAiOjE2MDM0Mjk4MDd9.eyJ1aWQiOjEsImF1dGhvciI6Ilx1NTk3ZFx1OTdmM1x1NWJhYiIsImFkbWluIjoxfQ.XT6h40ghE6aLxCisrLMbJG8stcP_ujMt1IpxVOMrO0w

Accédez au site officiel pour analyser les informations du jeton

On constate que les données sont les mêmes que notre définition, ce qui prouve que les deux premières parties sont normales, et l'étape suivante consiste à vérifier le jeton

Analyser le jeton pour extraire les données

Essayez d'analyser le jeton et d'extraire les données

Code JWT de référence

# 提取出header、payload、sign
headers = token.split(".")[0]
payload = token.split(".")[1]
sign = token.split(".")[2]

Pour déterminer si le jeton est valide, utilisez la même méthode pour chiffrer l'en-tête et la charge utile, et voyez si la signature obtenue est la même que le signe attaché au jeton

headers_payload = f"{headers}.{payload}"

new_sign = base64.urlsafe_b64encode(
  hmac.new(salt.encode('utf-8'), headers_payload.encode('utf-8'), hashlib.sha256).digest()).decode(
  'utf-8').replace(
  '=',
  '')
print(new_sign == sign)
# if new_sign == sign: 判断是否相等

S'ils sont identiques, prouvez que le jeton est valide, puis obtenez les informations d'en-tête ou de charge utile

if isinstance(payload, str):
  payload = payload.encode('ascii') 

rem = len(payload) % 4 
if rem > 0:
  payload += b'=' * (4 - rem)
# 上面这一部分是解密的部分数据补全格式

payload_data = base64.urlsafe_b64decode(payload) # 解码
data = json.loads(payload_data) # 加载payload信息为可以通过get方法获取里面的值
  
print(data.get("uid")) # 打印token里面的payload部分中的uid数据信息
print(data.get("author")) # 打印token里面的payload部分中的uid数据信息

Jusqu'à ce point

Nous avons créé le jeton avec succès et pouvons extraire la valeur du jeton

La prochaine étape consiste à encapsuler dans une classe en fonction de nos propres besoins

5. Articles de référence

documentation du site officiel de jwt.io

Python JWT 使用, par dawsonenjoy

Introduction à JSON Web Token , par Ruan Yifeng

Bienvenue à aimer ma page d'accueil personnelle GitHub
Hi Caiji

Je suppose que tu aimes

Origine blog.csdn.net/Jake_Lam/article/details/109272921
conseillé
Classement