El control de acceso es algo que está presente en casi cualquier aplicación, pues de una u otra manera debemos de ser capaces de detectar a los usuarios que intentan acceder a los recursos de nuestra aplicación, por lo que las aplicaciones siempre han contado con diversas estrategias para protegerse y negar el acceso a todas aquellas personas no autorizadas.
Lo que es un hecho es que, cada vez es más difícil garantizar la seguridad de las aplicaciones, pues con los años han salido diversas herramientas especializadas para quebrar la seguridad, sumado a esto, cada vez hay más profesionales que se dedican exclusivamente a quebrar la seguridad, por lo que los métodos de autenticación también deben de evolucionar.
Problemática
Durante años nos enseñaron que el usuario y password era los suficientemente seguro para autenticarnos en una aplicación, sin embargo, esto no es del todo cierto, y es que en la actualidad la autenticación mediante este método es considerado el más vulnerable de todos.
El problema con este método es que tenemos que enviar el usuario y password en cada petición, lo que hace que pueda ser captura por terceros de muchas formas, desde un simple Keylogger, ser capturado durante su viaje por la red o ser recuperado de algún medio persistente del lado del servidor, cómo por ejemplo, que el programador imprima por error el usuario y password en lo logs, los guarde sin encriptar en la base de datos o simplemente, quiere hacer un mal uso de la información por lo que guarda los password en algún otro lugar.
La imagen anterior muestra los puntos en que un password puede ser vulnerado, donde las líneas punteadas representan por donde el password podría viajas, mientras que las líneas rojas representan donde el password podrá ser capturado. En primer lugar, el usuario captura el password desde su equipo, donde un software de Keylogger podría guardar el password, luego el password es enviado al servidor, donde podría ser capturado por alguien que este escuchado la red, sobre todo en comunicaciones inseguras. Luego, el password llegar al servidor, donde creemos que el password ya está a salvo, sin embargo, el riesgo de ser vulnerado baja considerablemente, pero siempre existen factores de riesgo, como que el usuario guarde el password en los logs o lo guarde en las base de datos, por lo que eventualmente un usuario del sistema podría revisar el log o la base de datos y bingo, tiene el password, otro caso es que ese mismo password lo replicamos a otro sistema, lo que repite el riesgo anterior.
El problema de enviar los password es precisamente ese, que una vez que el password se envía al servidor no sabemos por cuantas personas o servicios pasará, además, un password siempre será válido hasta que el usuario lo cambie, pero si el usuario no sabe que ya fue vulnerado, porque habría de cambiarlo, por lo que la persona maliciosa tendrá acceso a sus sistemas por un tiempo indeterminado.
Otro problema es que con frecuencia utilizamos el mismo password para muchas de nuestras aplicaciones, como el correo electrónico, redes sociales, equipo de cómputo o incluso otros sistemas de la compañía, por lo que, en muchos de los casos, vulnerar una contraseña implica vulnerar varios de los accesos de ese mismo usuario.
Solución
La solución es clara, dejar de enviar el usuario y password en cada petición al servidor y en su lugar enviar un Token, el cual es una cadena de caracteres sin aparente significado, pero que el servidor puede descifrar y comprobar la autenticidad del usuario. Pero, antes que nada, describamos que es un Token.
Qué es un Token
Un token es una cadena alfanumérica con caracteres aparentemente aleatorios, como el siguiente:
Estas cadenas de texto, pueden no aparentar un significado, sin embargo, tiene un significado real para el servidor o institución que lo emitió, el cual puede entender y así, validar al usuario que intenta acceder a la información, e incluso, puede tener datos adicionales.
Un caso simple de tokens, es el dispositivo que dan los bancos para realizar transacciones desde internet, este token te genera un valor numérico que luego tenemos que ingresar al sistema, y de esta forma, el portal pueda asegurarse de que efectivamente somos nosotros y no un impostor.
En el caso de los tokens bancarios, no se almacena una información real dentro del Token, sino que simplemente es un valor generado que luego puede ser comprobado por el banco como un valor real generado por nuestro token. Sin embargo, existen tecnologías como JWT (Json Web Token) donde podemos enviar cualquier dato del cliente dentro del token para que el servidor pueda obtener mucha más información de nosotros.
Cómo funciona la autenticación con JWT
El primer paso es que el usuario obtenga un Token, para esto, se puede usar un sistema de login tradicional como usuario y password o incluso uno más fuerte, la idea es que de alguna forma el usuario se identifique con la aplicación.
Una vez, que el sistema valida al usuario, este le retorna un token. Una vez generado el token, es el cliente el responsable de guardarlo, pues de aquí en adelante, todas las peticiones que realice al servidor, deberán llevar el token.
Obteniendo un Token
No existe una regla de donde deba de ser guardado el token, ya que puede ser almacenado como una Cookie o en Local Storage si es que es un cliente web, o puede ser en la base de datos, si es que el usuario que consume el API es otra aplicación, la idea es que ese token lo deberemos conservar para futuras invocaciones al API.
Ya hemos hablado de como JWT funciona, pero ahora entraremos a ver cómo es la interacción que tiene un usuario al autenticarse por medio de JWT, para lo cual veamos la siguiente imagen:
Los pasos son los siguientes:
El usuario requiere de una autenticación tradicional con el servidor, es decir usuario y password (o cualquier otro tipo de autenticación).
El servidor validará que los datos introducidos sean correctos y generará un Token.
El servidor enviará el token al usuario y este lo tendrá que almacenar.
Una vez con el token, el usuario realiza una petición al servidor, enviando el token previamente generado.
El servidor validará que el token sea correcto.
Si el token es correcto, entonces el servidor retornará los datos solicitados.
Cabe mencionar que los puntos 4, 5 y 6 se pueden repetir indeterminado número de veces hasta que el token caduque, cuando esto pase, entonces será necesario reiniciar desde el paso 1.
Seguramente en este punto te preguntas, ¿de qué sirve el token si al final necesito enviar el usuario y password para crear el token? Y es una pregunta muy válida, pero existe una diferente enorme, para empezar, solo vamos a capturar el usuarios y password una vez, lo que reduce en gran medida la posibilidad de que nos intercepten las credenciales, en segundo lugar, las credenciales las mandamos solo al servicios que crea el token y no a todos los servicios del API, lo que limita la posibilidades de ser capturado a un solo servicio, por lo que podemos tener una mejor auditoría sobre ese servicio. Finalmente, cuando queramos consumir otro servicio, mandaremos el token y no el usuario y password, por lo que el token podrá validar nuestra identidad, pero no hay forma de saber con qué password se generó ese token.
Conclusiones
Hoy en día el uso de Tokens se ha venido popularizando rápidamente, no solo por la seguridad que implica, si no que permite mantener servicios sin estado del lado del servidor, lo que ha favorecido mucho a las API de tipo REST, pues ya no es necesario mantener una sesión del lado del servidor, ahorrando muchos recursos.
Por otro lado, no comprometemos la contraseña del usuario, pues un token puede ser validado e incluso, saber a qué usuario fue emitido, al mismo tiempo que podemos agregar datos, como privilegios fecha de caducidad, etc.
Acerca de este libro
Todo lo que acabas de ver en este artículo es solo una pequeña parte del libro Introducción a la arquitectura de software, el libro más completo en español sobre arquitectura de software, donde cubrimos los temas más importantes para convertirte en un arquitecto de software profesional.
¿Quieres convertirte en arquitecto de software pero no sabes cuál es el camino adecuando? o simplemente no sabes que guía estudiar para convertirte en arquitecto de software, te invito a que veas mi libro: