Estoy implementando un sistema de autenticación basado en token para una API REST usando un token de acceso de corta duración y un token de actualización de larga duración. Esta es una descripción general de los puntos finales API relevantes (HTTPS se aplica para todos los puntos finales):
Puntos finales:
POST /register/
POST /login/
POST /logout/
POST /password/change/
Implementación:
POST /register/
:
- Solicitud: el cliente envía un nombre de usuario, correo electrónico y contraseña en JSON.
- Acciones del servidor:
- Valida la entrada, crea un usuario en la base de datos (almacena el ID de usuario, nombre de usuario, correo electrónico y hash de contraseña).
- Crea un token de acceso de corta duración en formato JWT (contiene el ID de usuario, la fecha de emisión y la fecha de vencimiento).
- Crea un token de actualización de larga duración como una cadena UUID y lo almacena en la base de datos (almacena la identificación del usuario y el token de actualización).
- Respuesta: El servidor devuelve el token de acceso y el token de actualización en JSON.
POST /login/
:
- Solicitud: el cliente envía el nombre de usuario y la contraseña en JSON.
- Acciones del servidor:
- Valida la entrada, verifica si las credenciales son válidas verificando la base de datos.
- Si las credenciales son válidas, crea un token de acceso de corta duración y un token de actualización de larga duración como se mencionó anteriormente.
- Respuesta: Igual que
/register/
, devuelve el token de acceso y el token de actualización en JSON.
POST /logout/
:
- Solicitud: el cliente envía un token de actualización en el
Authorization
encabezado comoBearer
token. - Acciones del servidor:
- Valida el token de actualización marcando la base de datos de token de actualización.
- Elimina el token de actualización de la base de datos.
Nota: Esto deja el token de acceso válido, pero dado que será de corta duración (1 hora más o menos, creo que debería estar bien).
- Respuesta: Devuelve si la solicitud de cierre de sesión se procesó correctamente en JSON.
POST /password/change/
:
- Solicitud: el cliente envía el token de acceso en el
Authorization
encabezado comoBearer
token, y también envía la contraseña anterior y la nueva contraseña en JSON a través de HTTPS. - Acciones del servidor:
- Decodifica el token de acceso para recuperar al usuario y verifica la contraseña anterior del usuario con la base de datos.
- Establece el hash de contraseña del usuario en la base de datos en el hash de la nueva contraseña.
- Elimina todos los tokens de actualización asociados con el usuario en la base de datos de tokens de actualización para cerrar la sesión de las sesiones existentes (deja válidos los tokens de acceso de corta duración).
- Respuesta: Devuelve si la solicitud de cambio de contraseña se procesó correctamente en JSON.
Preguntas:
- ¿Es seguro este enfoque? Específicamente:
- ¿Es seguro enviar el nombre de usuario y la contraseña a través de JSON si se realiza a través de HTTPS? ¿Cómo evitaría que los dominios no autorizados realicen llamadas a este punto final? Además, ¿cómo evitaría los inicios de sesión programáticos?
- ¿Deberían los tokens de actualización ser procesados antes de almacenarlos en la base de datos, o simplemente estoy siendo paranoico?
- Si el cliente fuera un navegador web, ¿cómo almacenaría de forma segura el token de actualización en el cliente?
- Una idea que tengo para almacenar el token de actualización es: cuando el usuario inicia sesión, además de enviar el token de actualización al cliente, el servidor almacena el token en una
HttpOnly
cookie con unsecure
indicador. La autorización aún se realizará a través delAuthorization
encabezado, pero cuando el cliente se carga inicialmente, puede enviar unaGET
solicitud a un punto final que verifique si la cookie contiene un token de actualización válido y, de ser así, devolverlo al usuario en JSON. En otras palabras, el único momento en que la cookie se usará realmente es devolver el token de actualización dentro de la cookie al cliente. ¿Es seguro este enfoque? Creo que evitará CSRF ya que no hay efectos secundarios al solicitar el token de actualización de la cookie, pero ¿hay alguna otra forma en que un atacante pueda interceptar el token de actualización (suponiendo HTTPS)?
- Una idea que tengo para almacenar el token de actualización es: cuando el usuario inicia sesión, además de enviar el token de actualización al cliente, el servidor almacena el token en una