Comienzo a planificar una API REST con node.js, express y mongodb. La API proporciona datos para un sitio web (área pública y privada) y tal vez más tarde para una aplicación móvil. La interfaz se desarrollará con AngularJS.
Durante algunos días leí mucho sobre cómo proteger las API REST, pero no llego a una solución final. Por lo que yo entiendo es usar HTTPS para proporcionar una seguridad básica. Pero cómo puedo proteger la API en esos casos de uso:
Solo los visitantes / usuarios del sitio web / aplicación pueden obtener datos para el área pública del sitio web / aplicación
Solo los usuarios autenticados y autorizados pueden obtener datos para el área privada (y solo datos, donde el usuario otorgó permisos)
Por el momento, pienso permitir que solo los usuarios con una sesión activa utilicen la API. Para autorizar a los usuarios, usaré el pasaporte y, para obtener el permiso, debo implementar algo por mí mismo. Todo en la cima de HTTPS.
¿Alguien puede proporcionar algunas mejores prácticas o experiencias? ¿Hay una falta en mi "arquitectura"?
fuente
Respuestas:
He tenido el mismo problema que usted describe. Se puede acceder al sitio web que estoy construyendo desde un teléfono móvil y desde el navegador, por lo que necesito una API que permita a los usuarios registrarse, iniciar sesión y realizar algunas tareas específicas. Además, necesito admitir la escalabilidad, el mismo código que se ejecuta en diferentes procesos / máquinas.
Debido a que los usuarios pueden CREAR recursos (también conocidos como acciones POST / PUT), debe proteger su API. Puede usar oauth o puede crear su propia solución, pero tenga en cuenta que todas las soluciones pueden romperse si la contraseña es realmente fácil de descubrir. La idea básica es autenticar a los usuarios utilizando el nombre de usuario, la contraseña y un token, también conocido como apitoken. Este apitoken se puede generar usando node-uuid y la contraseña se puede cifrar usando pbkdf2
Luego, debe guardar la sesión en algún lugar. Si lo guarda en la memoria en un objeto plano, si mata el servidor y lo reinicia nuevamente, la sesión se destruirá. Además, esto no es escalable. Si usa haproxy para equilibrar la carga entre máquinas o si simplemente usa trabajadores, este estado de sesión se almacenará en un solo proceso, por lo que si el mismo usuario es redirigido a otro proceso / máquina, deberá autenticarse nuevamente. Por lo tanto, debe almacenar la sesión en un lugar común. Esto se hace típicamente usando redis.
Cuando el usuario se autentica (nombre de usuario + contraseña + apitoken) genera otro token para la sesión, también conocido como accesstoken. De nuevo, con nodo-uuid. Enviar al usuario el token de acceso y el ID de usuario. El ID de usuario (clave) y el token de acceso (valor) se almacenan en redis con el tiempo de caducidad, por ejemplo, 1 h.
Ahora, cada vez que el usuario realice cualquier operación utilizando la API de descanso, deberá enviar el ID de usuario y el token de acceso.
Si permite que los usuarios se registren utilizando la API de resto, deberá crear una cuenta de administrador con un apitoken de administrador y almacenarlos en la aplicación móvil (cifrar nombre de usuario + contraseña + apitoken) porque los nuevos usuarios no tendrán un apitoken cuando Se registran.
La web también usa esta api pero no es necesario que uses apitokens. Puede usar express con una tienda de redis o usar la misma técnica descrita anteriormente pero omitiendo el cheque de apitoken y devolviendo al usuario el userid + accesstoken en una cookie.
Si tiene áreas privadas, compare el nombre de usuario con los usuarios permitidos cuando se autentiquen. También puede aplicar roles a los usuarios.
Resumen:
Una alternativa sin apitoken sería usar HTTPS y enviar el nombre de usuario y la contraseña en el encabezado de Autorización y almacenar en caché el nombre de usuario en redis.
fuente
apitoken
? ¿Es una contraseña "secundaria"?Me gustaría contribuir con este código como una solución estructural para la pregunta planteada, de acuerdo (espero) con la respuesta aceptada. (Puedes personalizarlo muy fácilmente).
Este servidor se puede probar con curl:
fuente
Acabo de terminar una aplicación de muestra que hace esto de una manera bastante básica, pero clara. Utiliza mangosta con mongodb para almacenar usuarios y pasaportes para la gestión de autenticación.
https://github.com/Khelldar/Angular-Express-Train-Seed
fuente
Hay muchas preguntas sobre los patrones de autenticación REST aquí en SO. Estos son los más relevantes para su pregunta:
Básicamente, debe elegir entre usar claves API (menos seguras ya que un usuario no autorizado puede descubrir la clave), una combinación de clave de aplicación y token (medio) o una implementación completa de OAuth (más segura).
fuente
Si desea proteger su aplicación, entonces definitivamente debe comenzar usando HTTPS en lugar de HTTP , esto asegura una creación de un canal seguro entre usted y los usuarios que evitará rastrear los datos enviados de un lado a otro a los usuarios y ayudará a mantener los datos Intercambio confidencial.
Puede usar JWT (JSON Web Tokens) para asegurar API RESTful , esto tiene muchos beneficios en comparación con las sesiones del lado del servidor, los beneficios son principalmente:
1- Más escalable, ya que sus servidores API no tendrán que mantener sesiones para cada usuario (lo que puede ser una gran carga cuando tiene muchas sesiones)
2- Los JWT son independientes y tienen los reclamos que definen el rol del usuario, por ejemplo, y a qué puede acceder y emitido en la fecha y fecha de vencimiento (después de lo cual JWT no será válido)
3- Más fácil de manejar a través de equilibradores de carga y si tiene múltiples servidores API ya que no tendrá que compartir datos de sesión ni configurar el servidor para enrutar la sesión al mismo servidor, siempre que una solicitud con un JWT llegue a cualquier servidor, se puede autenticar y autorizado
4- Menos presión en su base de datos y no tendrá que almacenar y recuperar constantemente la identificación y los datos de la sesión para cada solicitud
5- Los JWT no pueden ser manipulados si usa una clave segura para firmar el JWT, por lo que puede confiar en los reclamos en el JWT que se envía con la solicitud sin tener que verificar la sesión del usuario y si está autorizado o no , solo puede verificar el JWT y luego estará listo para saber quién y qué puede hacer este usuario.
Muchas bibliotecas proporcionan formas fáciles de crear y validar JWT en la mayoría de los lenguajes de programación, por ejemplo: en node.js uno de los más populares es jsonwebtoken
Dado que las API REST generalmente tienen como objetivo mantener el servidor sin estado, los JWT son más compatibles con ese concepto ya que cada solicitud se envía con token de autorización que es autónomo (JWT) sin que el servidor tenga que realizar un seguimiento de la sesión del usuario en comparación con las sesiones que hacen que el servidor servidor con estado para que recuerde al usuario y su función, sin embargo, las sesiones también se usan ampliamente y tienen sus ventajas, que puede buscar si lo desea.
Una cosa importante a tener en cuenta es que debe entregar de forma segura el JWT al cliente utilizando HTTPS y guardarlo en un lugar seguro (por ejemplo, en el almacenamiento local).
Puede obtener más información sobre los JWT en este enlace.
fuente
Si desea tener un área completamente bloqueada de su aplicación web a la que solo puedan acceder los administradores de su empresa, entonces la autorización SSL puede ser para usted. Asegurará que nadie pueda conectarse a la instancia del servidor a menos que tenga un certificado autorizado instalado en su navegador. La semana pasada escribí un artículo sobre cómo configurar el servidor: Artículo
Esta es una de las configuraciones más seguras que encontrará, ya que no hay nombres de usuario / contraseñas involucrados para que nadie pueda acceder a menos que uno de sus usuarios entregue los archivos clave a un posible pirata informático.
fuente