"JWT", el esquema de inicio de sesión de autenticación que debe conocer

El nombre completo de JWT es JSON Web Token, que es una solución de autenticación entre dominios muy popular y se utiliza a menudo en escenarios de inicio de sesión único.

Algunas personas piensan que es muy fácil de usar. Después de usarlo, no hay necesidad de usar redis para implementar el proceso de autenticación en el lado del servidor. Sin embargo, algunas personas piensan que es inherentemente defectuoso y no se puede usar en absoluto.

¿Por qué es esto?

Método de autenticación tradicional

Hablando desde un escenario de inicio de sesión

Ha utilizado tantos sitios web y aplicaciones, muchos de los cuales requieren inicio de sesión, así que elija una escena de la que hablar.

Tome un sistema de comercio electrónico como ejemplo. Si desea realizar un pedido, primero debe registrar una cuenta. Después de tener una cuenta, debe ingresar un nombre de usuario (como un número de teléfono móvil o correo electrónico) y una contraseña para completar el proceso de inicio de sesión. Después de ingresar al sistema nuevamente dentro de un período de tiempo, no es necesario que ingrese el nombre de usuario y la contraseña. Solo cuando no haya iniciado sesión durante mucho tiempo (por ejemplo, no haya iniciado sesión durante un mes) para acceder al sistema, debe ingresar el nombre de usuario y la contraseña nuevamente.

Para aquellos sitios web o aplicaciones que se usan con frecuencia, generalmente no es necesario ingresar una contraseña durante mucho tiempo, por lo que después de cambiar una computadora o un teléfono móvil, no puede recordar las contraseñas de algunos sitios web o aplicaciones de uso frecuente. Arriba.

Método de autenticación de sesión de cookie temprana

La Internet primitiva estaba dominada por la web, y el cliente era un navegador, por lo que el método de sesión de cookies era el método de autenticación más utilizado en los primeros días. Hasta ahora, algunos sitios web todavía usan este método para la autenticación.

El proceso de certificación es aproximadamente el siguiente:

  1. El usuario ingresa el nombre de usuario, contraseña o usa el código de verificación de SMS para iniciar sesión en el sistema;
  2. Después de la autenticación del servidor, cree un mensaje de sesión, guarde SessionID en una cookie y envíelo de vuelta al navegador;
  3. La próxima vez que el cliente inicie una solicitud, automáticamente traerá la información de la cookie y el servidor obtendrá la información de la sesión a través de la cookie para su verificación;

"JWT", el esquema de inicio de sesión de autenticación que debe conocer

 

Pero, ¿por qué es un método de autenticación tradicional? Porque ahora todo el mundo tiene un teléfono inteligente y muchas personas no usan una computadora. Usualmente usan varias aplicaciones en sus teléfonos, como Taobao y Pinduoduo.
Bajo esta tendencia, la Cookie-Session tradicional ha encontrado algunos problemas:
1. En primer lugar, Cookie-Session solo se puede utilizar en escenarios web, si es una APP, no hay lugar para que la APP almacene cookies.
Los productos actuales ofrecen básicamente dos formas de uso tanto web como de APP, y algunos productos incluso solo tienen APP.

2. Dé un paso atrás y diga que el producto que crea solo es compatible con la web y que también se deben considerar los problemas entre dominios, pero las cookies no pueden cruzar dominios.
Tome Tmall Mall como ejemplo. Cuando ingrese al Tmall Mall, verá menús como Tmall Supermarket, Tmall Global y Tmall Members en la parte superior. Al hacer clic en estos menús, se ingresarán diferentes dominios. Las cookies en diferentes dominios son diferentes. No puede obtener las cookies del dominio B en el dominio A, incluso si es un subdominio.

"JWT", el esquema de inicio de sesión de autenticación que debe conocer

 

3. Si es un servicio distribuido, se debe considerar la sincronización de sesiones.
Los sitios web y las aplicaciones de Internet de hoy son básicamente implementaciones distribuidas, es decir, hay más de una máquina en el lado del servidor. Cuando un usuario realiza una operación de inicio de sesión en la página, la acción de inicio de sesión debe ser una solicitud a uno de los servidores. Tienes que guardar tu información de identidad, la forma tradicional es guardar la sesión.

Luego vino la pregunta. Ha visitado varias páginas. En este momento, la carga de una solicitud se equilibra y se enruta a otro servidor (no al que inició sesión). Cuando el fondo recibe la solicitud, necesita verificar la información de identidad y los permisos del usuario, por lo que la interfaz comienza a obtener la información del usuario de la sesión. Sin embargo, este servidor no es el que inició sesión en ese momento, y su sesión no se guarda, por lo que el servicio en segundo plano piensa que usted es un usuario no registrado y no puede devolverle datos.

Por lo tanto, para evitar esta situación, es necesario realizar una sincronización de sesión. Después de que un servidor recibe la solicitud de inicio de sesión, después de que el servidor actual guarda la sesión, también necesita sincronizarse con varios otros servidores.

4. Las cookies tienen el riesgo de CSRF (falsificación de solicitudes entre sitios). La falsificación de solicitudes entre sitios es un método de ataque que obliga a los usuarios a realizar operaciones no intencionales en las aplicaciones web que han iniciado sesión actualmente. CSRF utiliza la confianza del sitio web en el navegador web del usuario. En pocas palabras, el atacante utiliza algunos medios técnicos para engañar al navegador del usuario para que visite un sitio web que haya autenticado y realice algunas operaciones (como comprar productos). Dado que el navegador ha sido autenticado, el sitio web visitado será considerado como una operación iniciada por un usuario real.
Por ejemplo, soy un hacker y encontré una vulnerabilidad CSRF en un sitio web técnico que visita con frecuencia. Los artículos de publicación admiten el formato html, y luego agrego contenido peligroso en html, como

 <img src="http://www.examplebank.com/withdraw?account=Alice&amount=1000&for=Badman">

Suponiendo que la dirección apuntada por src es la dirección de pago de su sitio web de compras habitual (por supuesto, es solo un ejemplo, el ataque real no es tan simple), si ha iniciado sesión antes y se ha guardado la cookie que identifica su información de identidad. Cuando escanee el artículo que publiqué, el ataque CSRF funcionará tan pronto como se cargue la etiqueta img, y pagará este sitio web sin su conocimiento.

Versión modificada de Cookie-Session

Dado que existen muchos problemas con la autenticación tradicional de sesión de cookies, el esquema anterior se puede modificar.
1. Modificación de la cookie Dado que la cookie no se puede usar en un navegador que no sea una aplicación, entonces no use cookies para el almacenamiento del lado del cliente y use otros métodos en su lugar.
¿A qué cambiar?
El almacenamiento local se puede usar en la web, y la base de datos del cliente se puede usar en la APLICACIÓN, lo que puede lograr un dominio cruzado y evitar CSRF.

2. El servidor ya no guarda la Sesión, saca la información de la Sesión y guárdala en una base de datos de memoria como Redis, lo que mejora la velocidad y evita problemas de sincronización de Sesión;

Después de la transformación, se convierte en el siguiente proceso de certificación:

  1. El usuario ingresa el nombre de usuario, contraseña o usa el código de verificación de SMS para iniciar sesión en el sistema;
  2. Se verifica el servidor, la estructura de datos construida por la información de autenticación se almacena en Redis y el valor de la clave se devuelve al cliente;
  3. El cliente obtiene la clave devuelta y la almacena en el almacenamiento local o en la base de datos local;
  4. La próxima vez que el cliente vuelva a solicitar, agregue el valor de la clave al encabezado o al cuerpo de la solicitud;
  5. El servidor obtiene información de autenticación de Redis de acuerdo con la clave obtenida;

Las siguientes dos imágenes demuestran, respectivamente, el proceso del primer inicio de sesión y el no primer inicio de sesión.

"JWT", el esquema de inicio de sesión de autenticación que debe conocer

 

"JWT", el esquema de inicio de sesión de autenticación que debe conocer

 

Después de una feroz transformación, los problemas del método tradicional Cookie-Session han sido resueltos. Esta transformación debe ser realizada por el desarrollador del proyecto. Definitivamente, la transformación requiere mucho tiempo y es laboriosa, y puede haber lagunas.

Apariencia de JWT

En este momento, JWT está listo para jugar. JWT es una implementación específica de la versión modificada de Cookie-Session, que le ahorra tiempo para hacer ruedas usted mismo. JWT tiene otra ventaja, es decir, no necesita almacenar información de autenticación en el servidor ( Por ejemplo, token), que es totalmente proporcionado por el cliente.El servidor puede verificar la legitimidad del usuario según el algoritmo de descifrado proporcionado por el propio JWT, y este proceso es seguro.

Si es nuevo en JWT, el punto más cuestionable puede ser: ¿Por qué JWT puede confiar completamente en el lado del cliente (como el lado del navegador) para realizar la función de autenticación, y toda la información de autenticación existe en el lado del cliente. ¿Cómo garantizar la seguridad?

Estructura de datos JWT

La forma final de JWT es una cadena, que consta de tres partes: encabezado , carga útil y firma , separadas por " . ". Como el siguiente:

"JWT", el esquema de inicio de sesión de autenticación que debe conocer

 

cabeza

El encabezado se expresa en formato JSON y se utiliza para indicar el tipo de token y el algoritmo de cifrado. El formato es el siguiente, lo que significa que se utiliza el formato JWT y el algoritmo de encriptación es HS256. Este es el algoritmo más utilizado y hay muchos otros.

{
  "alg": "HS256",
  "typ": "JWT"
}

En correspondencia con la parte del encabezado rojo de la figura anterior, se requiere la codificación Base64.

Carga

Se utiliza para almacenar los datos requeridos por el servidor, como información del usuario, como nombre, sexo, edad, etc. Cabe señalar que aquí no se debe colocar información confidencial importante, como contraseñas.

{
  "name": "古时的风筝",
  "introduce": "英俊潇洒"
}

Además, JWT también especifica 7 campos para que los desarrolladores elijan.

  • iss (emisor): Emisor
  • exp (tiempo de vencimiento): tiempo de vencimiento
  • sub (asunto): Asunto
  • aud (audiencia): audiencia
  • nbf (no antes): tiempo efectivo
  • iat (Emitido en): hora de emisión
  • jti (ID de JWT): número

Esta parte de la información también debe estar codificada en Base64.

firma

La firma tiene una fórmula de cálculo.

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

Este método, calculado mediante el algoritmo HMACSHA256, tiene dos parámetros: el primer parámetro es (encabezado codificado en base64 + carga útil codificada en base64) conectado por puntos, y el último parámetro es una clave de cadena personalizada. Exponer al cliente, pero el servidor debe saberlo.

Cómo utilizar

Después de comprender la estructura y el algoritmo de JWT, ¿cómo usarlo? Supongamos que tengo un sitio web aquí.

1. Cuando los usuarios inician sesión en el sitio web, deben ingresar un nombre de usuario, contraseña o verificación por SMS para iniciar sesión. Cuando la solicitud de inicio de sesión llega al servidor, el servidor verifica la cuenta y la contraseña, luego calcula la cadena JWT y la devuelve al cliente.

2. Una vez que el cliente obtiene la cadena JWT, se almacena en la cookie o en LocalStorage del navegador.

3. Vuelva a enviar la solicitud, como cuando solicita al usuario que configure la página, agregue la cadena JWT al encabezado de la solicitud HTTP o póngala directamente en el cuerpo de la solicitud.

4. Una vez que el servidor obtiene esta cadena de cadenas JWT, utiliza el encabezado base64 y la carga útil base64 para calcular la parte de la firma a través del algoritmo HMACSHA256, y compara si el resultado del cálculo es coherente con la parte de la firma transmitida. Si son coherentes, se indica la solicitud No hay problema. Si son inconsistentes, la solicitud ha expirado o es una solicitud ilegal.

"JWT", el esquema de inicio de sesión de autenticación que debe conocer

 

"JWT", el esquema de inicio de sesión de autenticación que debe conocer

 

Cómo garantizar la seguridad

La clave para garantizar la seguridad es HMACSHA256 o el mismo tipo de algoritmo de cifrado Dado que el proceso de cifrado es irreversible, no se puede descifrar la información clave de acuerdo con el JWT transmitido al front-end.

Además, las firmas obtenidas después del cifrado de diferentes encabezados y cargas útiles son diferentes. Por lo tanto, si alguien cambia la información en la parte de carga útil, el resultado final cifrado debe ser diferente al anterior al cambio, por lo que la verificación final El resultado es una solicitud ilegal.

¿Es seguro que otros obtengan el JWT completo?

Suponiendo que la parte de carga útil almacena los campos relacionados con el nivel de autoridad, el ladrón quiere modificarlo a un nivel de autoridad más alto después de obtener la cadena JWT. Como se mencionó anteriormente, definitivamente no tendrá éxito en este caso, porque la firma encriptada no será exitosa. Del mismo modo, el servidor se puede identificar fácilmente.

Entonces, si el ladrón no hace cambios y lo usa directamente después de obtenerlo, no hay manera. Para evitar ser robado por el ladrón en mayor medida, se debe usar el protocolo HTTPS en lugar del protocolo HTTP, que puede prevenir efectivamente algunos ataques de secuestro intermedio. .

Algunos estudiantes están a punto de decir, esto no es seguro, puede simular fácilmente la solicitud después de obtener la cadena JWT. Este es de hecho el caso, pero la premisa es cómo se puede conseguir ¿Hay alguna otra forma además del secuestro intermedio mencionado anteriormente?

A menos que el ladrón se lleve su computadora directamente, en ese caso, lo siento, no solo JWT es inseguro, sino que otros sitios web y métodos de autenticación son inseguros.

"JWT", el esquema de inicio de sesión de autenticación que debe conocer

 

Aunque estos casos son raros, aún debe prestar atención a establecer el tiempo de vencimiento de manera razonable cuando use JWT, no demasiado.

una pregunta

Hay un problema con JWT que ha provocado que muchos equipos de desarrollo dejen de usarlo. Una vez que se emite un token JWT, el servidor no puede descartarlo a menos que caduque. Hay muchas aplicaciones que permiten que solo se use normalmente el último cliente de inicio de sesión de forma predeterminada, y el inicio de sesión de múltiples terminales no está permitido. JWT no puede hacerlo porque se emite un nuevo token, pero el antiguo aún está disponible antes de que caduque. En este caso, el servidor debe agregar la lógica correspondiente.

Bibliotecas JWT de uso común

El sitio web oficial de JWT enumera las bibliotecas correspondientes a varios idiomas, entre las que se encuentran las de Java.

"JWT", el esquema de inicio de sesión de autenticación que debe conocer

 

Tome java-jwt como ejemplo.

1. Importe el paquete Maven correspondiente.

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.10.3</version>
</dependency>

2. Al iniciar sesión, llame al método de creación para obtener un token y devolverlo a la interfaz.

public static String create(){
  try {
    Algorithm algorithm = Algorithm.HMAC256("secret");
    String token = JWT.create()      .withIssuer("auth0")
      .withSubject("subject")
      .withClaim("name","古时的风筝")
      .withClaim("introduce","英俊潇洒")
      .sign(algorithm);    System.out.println(token);
    return token;
  } catch (JWTCreationException exception){
    //Invalid Signing configuration / Couldn't convert Claims.
    throw exception;
  }
}

3. Después de iniciar sesión correctamente, coloque el token en el encabezado o en el cuerpo de la solicitud cuando la solicitud se inicie nuevamente y el servidor verifique el token.

public static Boolean verify(String token){
  try {
    Algorithm algorithm = Algorithm.HMAC256("secret");
    JWTVerifier verifier = JWT.require(algorithm)
      .withIssuer("auth0")
      .build(); //Reusable verifier instance
    DecodedJWT jwt = verifier.verify(token);    String payload = jwt.getPayload();    String name = jwt.getClaim("name").asString();
    String introduce = jwt.getClaim("introduce").asString();
    System.out.println(payload);    System.out.println(name);    System.out.println(introduce);    return true;
  } catch (JWTVerificationException exception){
    //Invalid signature/claims
    return false;
  }}

4. Utilice el método de creación para generar el token y verifíquelo con el método de verificación.

public static void main(String[] args){
  String token = create();
  Boolean result = verify(token);
  System.out.println(result);}

Obtén el siguiente resultado

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzdWJqZWN0IiwiaW50cm9kdWNlIjoi6Iux5L-K5r2H5rSSIiwiaXNzIjoiYXV0aDAiLCJuYW1lIjoi5Y-k5pe255qE6aOO562dIn0.ooQ1K_XyljjHf34Nv5iJvg1MQgVe6jlphxv4eeFt8pA
eyJzdWIiOiJzdWJqZWN0IiwiaW50cm9kdWNlIjoi6Iux5L-K5r2H5rSSIiwiaXNzIjoiYXV0aDAiLCJuYW1lIjoi5Y-k5pe255qE6aOO562dIn0
古时的风筝英俊潇洒true

Se puede verificar la cadena JWT creada con el método de creación.

Y si modifico la parte de la carga útil de la cadena JWT y la parte entre los dos puntos, y luego llamo al método de verificación para verificar, se producirá una JWTVerificationException y no se podrá pasar la verificación.

Supongo que te gusta

Origin blog.csdn.net/GYHYCX/article/details/108779217
Recomendado
Clasificación