Un artículo para comprender Token (JWT) [código de Python]

1. Conozca Token por primera vez

Permítanme hablar sobre lo que es un token. El token aquí se refiere a JWT (Json Web Token) por defecto.

Experimente Json Web Token

Genere JWT en línea

tipo de token

Token tradicional

El token tradicional es que después de que un usuario inicia sesión, el servidor le devuelve un token al usuario para que lo guarde. Este token puede ser una combinación de varias letras aleatorias y el servidor retiene el mismo token (por ejemplo, usando redis para almacenar el token)

Cuando el usuario accede a otras interfaces, debe llevar este token, y luego el servidor juzga si este token existe en redis para juzgar si el usuario ha iniciado sesión o tiene los permisos correspondientes.

JWT (token web json)

A diferencia de los tokens tradicionales, los tokens web json no necesitan mantenerse en el servidor.

Flujo de procesamiento:

Una vez que el usuario inicia sesión, el servidor calcula y devuelve un token cifrado de acuerdo con ciertas reglas. El token contiene cierta información necesaria del usuario, como la identificación del usuario y la fecha de vencimiento del token.

Cuando los usuarios acceden a otras interfaces, deben llevar este token, y luego el servidor verifica este token con una contraseña

  • Verifique que el token sea el token enviado por el servidor
  • Verificar el tiempo de vencimiento del token

Una vez que todo está correcto, se considera que el usuario ha iniciado sesión y tiene los permisos correspondientes.

¿Dónde se usará el token?

En nuestro desarrollo, donde el front-end y el back-end están separados, a menudo es necesario proporcionar autenticación para servicios multi-end, como móviles, web y pequeños programas Hay miles de usuarios y miles de interfaces.

¿Y cómo podemos asegurarnos de que cada interfaz solo permita el acceso de usuarios autorizados? (Por ejemplo, solo el administrador puede acceder o solo el usuario que inició sesión puede acceder)

La solución es devolver un JWT al usuario y luego juzgar a partir de este token si el usuario de la interfaz de acceso actual cumple con nuestra configuración.

2. Características de Json Web Token

ventaja

  • No es necesario almacenar la información del estado de inicio de sesión del usuario en el servidor (como redis)
  • El mismo Token se puede usar en diferentes servidores, entornos e incluso diferentes servicios comerciales (siempre que la clave esté configurada)
  • Se puede usar en dispositivos móviles, web, applet, etc.

Desventaja

Por supuesto que hay desventajas

Por ejemplo, se necesita tiempo para generar y analizar el token. En comparación con los métodos tradicionales de verificación de token, la generación y el análisis de JWT llevará más tiempo.

Por ejemplo, el token existente no se puede cancelar (si el token se filtra, incluso si el usuario ha cambiado la contraseña dentro del período de validez del token, el atacante aún puede usar el token para hacer lo que quiera)

3. Principio de token

Si ha ingresado al sitio web de generación de JWT en línea , puede ver esta imagen

El token web Json contiene tres partes, encabezado, datos y firma

Estructura JWT

cabeza

El encabezado puede incluir información sobre el token, como información sobre el algoritmo de cifrado, la hora en que se creó el token y el tiempo de vencimiento, y luego usar base64 para el cifrado.

Nota (los datos cifrados en base64 pueden ser descifrados por cualquier persona, lo que equivale a transparentes)

como

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

datos

Los datos pueden incluir alguna identificación de usuario, nivel de permiso, etc., pero no coloque datos secretos, como (contraseña del usuario, nombre real del usuario)

Nota (porque cualquiera puede descifrar el encabezado y los datos usando base64)

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

firma

La parte de la firma es la esencia de JWT. Las dos cadenas de encabezado y datos están cifradas y cifradas. Este hash es diferente del cifrado base64. El cifrado hash requiere una contraseña, que no se puede revelar al usuario. , Es decir, el contenido cifrado es irreversible

Por ejemplo, el método de cifrado es el siguiente

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

Qué significa eso?

Por ejemplo, la parte del encabezado registra la creación a las 7 en punto y la expiración a las 8 en punto, lo que significa que el período de validez es de una hora.

La parte de datos registra la identificación de un determinado usuario.

En este momento, después de cifrar el servidor con una contraseña, se formará una cadena de cadenas (siempre que los datos en el encabezado y las partes de datos no se modifiquen, se formará la misma cadena cada vez que se realice el cifrado)

Puede acceder a la interfaz de servicio entre las 7 y las 8 en punto y se puede utilizar normalmente

Sin embargo , a las 9 en punto, el pirata informático encontró su token, pero el token expiró, luego el pirata informático cambió la hora de vencimiento del encabezado y luego usó este token para acceder a la interfaz del servicio

En este momento habrá un error, ¿por qué?

Porque después de que se cambia la información del encabezado, la firma cambiará, pero el hacker no generó la contraseña del token y el hacker no puede construir la firma correcta.

Cuando el token se verifica en segundo plano, el encabezado y la parte de datos se cifrarán con una contraseña para generar una firma y luego se compararán con el token enviado para ver si es coherente

4. Generar token

Python se usa aquí para demostrar la generación de token

Primero tenemos que importar varios paquetes

import time
import json
import base64
import hashlib
import hmac

Son herramientas para obtener la hora actual, generar y analizar el formato json y cifrar

Prepare dos parámetros de antemano

exp=60 # token有效期 秒

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

Encabezado de procesamiento

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

Encabezado cifrado

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

Procesamiento de carga útil de datos

La carga útil aquí almacena algunos datos del usuario (uid, rol, etc.). Nota: No coloque aquí datos privados (como contraseñas de usuario, etc.)

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

Carga útil cifrada

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

Firma criptográfica

La tercera parte es la firma, la firma necesita usar salt, que es la contraseña encriptada

Después de empalmar las dos primeras partes, use el cifrado hash para cifrar las dos partes de la firma para obtener una cadena, que se llama firma.

# 拼接前两部分
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)

Vaya al sitio web oficial para analizar la información del token

Imprime nuestro token, copia el token

eyJ0eXAiOiJ5Z3QiLCJleHAiOjE2MDM0Mjk4MDd9.eyJ1aWQiOjEsImF1dGhvciI6Ilx1NTk3ZFx1OTdmM1x1NWJhYiIsImFkbWluIjoxfQ.XT6h40ghE6aLxCisrLMbJG8stcP_ujMt1IpxVOMrO0w

Vaya al sitio web oficial para analizar la información del token

Se encuentra que los datos son los mismos que en nuestra definición, lo que prueba que las dos primeras partes son normales, y el siguiente paso es verificar el token.

Analizar el token para extraer datos

Intente analizar el token y extraer datos

Código JWT de referencia

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

Para determinar si el token es válido, use el mismo método para cifrar el encabezado y la carga útil, y vea si la firma obtenida es la misma que el signo adjunto al token

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: 判断是否相等

Si son iguales, pruebe que el token es válido y luego obtenga el encabezado o la información de carga útil

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数据信息

A este punto

Hemos creado correctamente el token y podemos extraer el valor del token.

El siguiente paso es encapsularlo en una clase de acuerdo con nuestras propias necesidades.

5. Artículos de referencia

Documentación del sitio web oficial jwt.io

Python JWT 使用, por dawsonenjoy

Tutorial introductorio de JSON Web Token , por Ruan Yifeng

Bienvenido a me gusta en mi página de inicio personal de GitHub
Hi Caiji

Supongo que te gusta

Origin blog.csdn.net/Jake_Lam/article/details/109272921
Recomendado
Clasificación