Hoy en día, el esquema de seguridad que se basa en dos tokens es bastante común. Hay mucha información sobre el tema en Internet. A menudo solo hay una descripción de qué son los tokens de actualización y acceso y cómo usarlos.
Para comprender el concepto detrás de los tokens, me gustaría hacer un experimento de pensamiento simple.
Imaginemos que usted es un estudiante al que le gusta el dinero pero a menudo tiene alrededor de cero en el saldo de su cuenta.
En el camino a su universidad, abre la aplicación móvil de su banco para verificar el saldo de su cuenta.
Para mostrarle que una aplicación de saldo necesita ejecutar una solicitud al servidor del banco:
GET http://api.mybank.com/balance HTTP 1.1
y recibe respuesta
{ balance: '$0.0' }

Sería bueno si nadie, excepto usted, pudiera verificar su cuenta bancaria. Para hacerlo, agreguemos un encabezado especial con el nombre de usuario y su contraseña única:
`Autorización: Nombre de usuario Contraseña
Autorización: JohnDwayson QWERTY1`
Ahora el servidor puede autenticarlo con su nombre de usuario y contraseña personales. Significa que el par JohnDwayson QWERTY1 debe mantenerse en un lugar secreto en su teléfono móvil para protegerse de alguien a quien no se le permite gastar su dinero. Sería aún mejor si pudiéramos evitar almacenar la contraseña pero nadie quiere ingresarla con demasiada frecuencia.
Cuando usamos nuestra aplicación móvil durante 30 minutos en un autobús, enviará su contraseña a través de la red muchas veces en 30 minutos.

Cada requset contiene contraseña
Continuemos nuestro experimento mental. Todavía estás en un autobús y tu aplicación envía una solicitud al servidor.
¿Qué sucede si hay un fraude a su alrededor en un autobús y él puede interceptar uno o pocos paquetes http desde su teléfono móvil al servidor del banco?
Si la aplicación actualiza la información cada minuto, el fraude tendrá 30 posibilidades para cruzar las solicitudes y obtener su contraseña.
Supongamos que robó 5-6 mensajes. Su contraseña ahora está comprometida y el fraude puede usarla para acceder a la información de su cuenta.

El hombre en el medio puede escuchar la contraseña
¿Qué puede hacer él con esta información? Buenas noticias de que no puede gastar su dinero ya que usted no lo tiene ... todavía :) Tampoco puede cambiar su contraseña, ya que en este caso lo notará y puede usar SMS de un banco para recuperar la contraseña. La antigua contraseña robada en este caso ya no será válida y el estudiante ahorrará su dinero
Pero lo que puede hacer es seguir revisando su saldo en paralelo con usted. Puede escribir fácilmente un script de Python que verificará su cuenta cada 10 segundos y tan pronto como reciba dinero, puede gastar cada centavo para comprar bitcoins. Probablemente sea peor si su guión gastara entre 5 y 10 dólares cada día, y es probable que no se note durante los meses o años.

Hacker espera tu dinero
Para evitar esto, podemos pedirle al usuario que cambie su contraseña después de un tiempo. Digamos que la contraseña será válida por 3 meses. Lo bueno es que después de 3 meses perderá el acceso a su cuenta. Lo malo es que perderá el acceso a su cuenta solo después de 3 meses. Obviamente, para evitar esto, podemos pedirle que cambie su contraseña cada mes o semana. Pero puede ser molesto para los usuarios finales.
Sería bueno si no usamos nuestra contraseña con demasiada frecuencia en nuestras solicitudes. Para hacerlo, podemos presentar un punto final especial: http://api.mybank.com/login . Vamos a enviar nuestras credenciales solo a este punto final y, a cambio, el servidor generará para nosotros un token especial. Sea solo una cadena única, GUID, que el servidor almacena en su base de datos. Llamemos a esta cadena única es token de acceso. Lo usaremos en lugar de nuestro nombre de usuario y contraseña en el encabezado de cada solicitud de conversación con el servidor. Similar a la contraseña, configuremos el tiempo de vencimiento para el token de acceso.

Para actualizar el saldo no necesitamos una contraseña
Reproduzcamos nuestro experimento mental.
Estamos en el autobús y alguien robó nuestra solicitud http para verificar el saldo. Pero ahora el fraude solo tiene token de acceso.

No es suficiente robar solo token de acceso
¿Qué hacker puede hacer ahora con esta información? En primer lugar, él todavía no puede gastar su dinero. En segundo lugar, no puede cambiar la contraseña, ya que simplemente no la conoce. Además, ahora el tiempo de vencimiento de la contraseña y el token de acceso es dos configuraciones separadas. Podemos dejar el tiempo de caducidad de la contraseña como 3 meses y debemos elegir la caducidad del token de acceso. Nos gustaría establecer este tiempo lo más corto posible, porque para obtener un nuevo token de acceso no podemos usar el token en sí. Si alguien roba esta ficha, podrá renovarla todo el tiempo que quiera.
Cuando el token de acceso caduca, para obtener uno nuevo debemos enviar nuevamente las credenciales de usuario. Si está en un autobús durante los 30 minutos y su tiempo de vencimiento para el token de acceso es de 15 minutos, debe enviar su contraseña al menos 2 veces. Por lo general, queremos actualizar el token de acceso antes, digamos cada 10 minutos, de lo contrario, el usuario puede notar algunos retrasos para obtener un nuevo token. Además, resuelve el problema cuando fallan pocas solicitudes al mismo tiempo debido al token caducado y debemos volver a intentarlo en el orden correcto después de obtener un token nuevo.
Ahora los resultados son mejores. El fraude tiene acceso a nuestros datos solo durante 10 minutos en lugar de 3 meses. Pero todavía tiene un buen cambio para robar nuestra contraseña y es posible que no nos demos cuenta hasta que robe nuestro dinero.
El problema ahora es obtener el token de acceso, aún necesitamos la contraseña. ¿Qué pasa si vamos a generar una cadena única más? Un token especial utilizado solo para obtener token de acceso.
Para lograr esto, nuestro punto final de inicio de sesión debe aceptar nombre de usuario y contraseña y devolver un nuevo token llamado token de actualización. Que almacenaremos en nuestra aplicación móvil. El token de actualización puede tener un tiempo de vencimiento más largo, por ejemplo, un mes.

Renueve el flujo para los tokens de actualización y acceso
Cada vez que necesitamos renovar el token de acceso, necesitamos enviar solo un token de actualización. Por lo tanto, nuestra contraseña se enviará al servidor solo una vez al mes o rara vez. Básicamente solo necesitamos contraseña solo para recuperar el primer token de actualización.
Todavía necesitamos token de acceso para ejecutar solicitudes para obtener algunos datos del servidor. Entonces
POST /login with username and password returns us refresh token
POST /renew with refresh token returns us access token
POST /balance with access token returns us actual balance
Repitamos nuestro experimento nuevamente.
Estamos en un bus Nuestro estudiante está revisando su saldo.
Pero ahora nuestra aplicación utiliza un token de actualización que se almacena en algún lugar de un archivo en el teléfono móvil.
La aplicación está enviando solicitudes como:
POST /renew
GET /balance
GET /balance
GET /balance
POST /renew
GET /balance
GET /balance
GET /balance
Como antes, el pirata informático se cruza con pocas solicitudes con token de acceso en un bus.
Como el tiempo de vencimiento para el token de acceso es de 15 minutos y estamos actualizando los tokens cada 10 minutos.
El hacker puede usar información robada solo por 10 minutos o menos.
¿Qué sucede si se cruza con una de las solicitudes / renovar y tiene token de actualización y acceso? Teóricamente, puede usar el token de actualización durante un mes para obtener nuevos tokens de acceso y aún así poder robar dinero.
Pero si regeneramos ambos tokens en cada solicitud de renovación / y el servidor almacena solo un token de actualización a la vez. La copia de fraude del token de actualización también se volvió inválida en 10 minutos y no puede usarla sin avisarnos que el token está comprometido. Si intenta renovar el token, invalidará nuestro token y nos veremos obligados a volver a iniciar sesión.
Una ventaja más del token de actualización es que no necesitamos almacenar la contraseña en una aplicación o navegador y solo almacenamos el último token de actualización.
Lo interesante es que el token de acceso no puede ser solo una cadena aleatoria, sino que puede contener información útil. Por ejemplo, puede ser tiempo de vencimiento, ID de usuario y rol de usuario. En este caso, se denomina token autónomo y el servidor no necesita acceso a la base de datos para validar el token y los permisos del usuario. Puede ser muy útil en microservicios ya que puede aumentar el rendimiento y disminuir el acoplamiento entre microservicios.
Está un poco fuera del tema del artículo, pero vale la pena mencionar el scope
.
¿Qué sucede si pediremos / renovaremos el punto final solo para el token de acceso que puede usarse exclusivamente para verificar el saldo?
Si el usuario quiere gastar algo de dinero, ¿debería recibir un segundo token diferente por eso? Podemos llamar a este parámetro 'alcance'.
Entonces podemos pedir / renovar? Scope = [balance, noticias]. Si nuestro pirata informático aún conserva este token, ¡no puede usarlo para gastar nuestro dinero!
La idea basada en dos tokens brinda una mayor seguridad de uso que solo una contraseña o un token por diseño. En lugar de elegir una contraseña más larga o algoritmos de seguridad más fuertes.
Esta fue mi explicación del concepto básico detrás de los tokens y cómo funcionan.
En una práctica, hay algunas implementaciones diferentes de este concepto que se pueden buscar fácilmente en Google.
Pequeña nota sobre la flexibilidad para elegir un tiempo de vencimiento para la contraseña y los tokens.
El tiempo de vencimiento típico puede ser:
Para la contraseña es de 3 a 6 meses. Es bueno tener esta limitación. Como las bases de datos pueden ser robadas y el usuario puede reutilizar la misma contraseña en todos los servicios.
Para el token de actualización, el tiempo de vencimiento puede ser de aproximadamente una semana o un mes. Para las personas que trabajan en una oficina con algún sitio web, es útil tener este tiempo al menos más de un fin de semana. De lo contrario, deben ingresar la contraseña todos los lunes.
El tiempo de vencimiento del token de acceso puede estar en un rango de 10 a 60 minutos. Un tiempo más corto requiere más solicitudes de renovación, pero un tiempo más largo puede dar más posibilidades de fraude.
Conclusión
Necesitamos usar una contraseña para obtener un token de actualización de larga duración. Luego envíe un token de actualización para obtener un token de acceso de corta duración. Que utilizar token de acceso para ejecutar solicitudes útiles.