sistema - Autenticación API REST para aplicaciones web y aplicaciones móviles
laravel passport tutorial español (3)
Tengo problemas para decidir cómo implementar la autenticación para una API RESTful que será segura para el consumo tanto de una aplicación web como de una aplicación móvil.
En primer lugar, pensé investigar la Autenticación HTTP básica sobre HTTPS como una opción. Funcionaría bien para una aplicación móvil, donde el nombre de usuario y la contraseña podrían almacenarse en el llavero del sistema operativo de forma segura y no podrían ser interceptados en tránsito, ya que la solicitud sería a través de HTTPS. También es elegante para la API, ya que será completamente apátrida. El problema con esto es para la aplicación web. No habrá acceso a tal llavero para almacenar el nombre de usuario y la contraseña, así que necesitaría usar una cookie o localStorage, pero luego estoy almacenando los detalles privados del usuario en un lugar fácilmente accesible.
Después de más investigaciones, encontré muchas conversaciones sobre la autenticación HMAC. El problema que veo con este enfoque es que debe haber un secreto compartido que solo el cliente y el servidor conozcan. ¿Cómo puedo obtener este secreto por usuario para un usuario particular en la aplicación web, a menos que tenga un punto final de API / inicio de sesión que tenga nombre de usuario / contraseña y devuelva el secreto para almacenarlo en una cookie? para usar en futuras solicitudes. Sin embargo, esto está introduciendo estado a la API.
Para lanzar otra llave inglesa en las obras, me gustaría poder restringir la API a ciertas aplicaciones (o, para poder bloquear el uso de la API de ciertas aplicaciones). No veo cómo esto sería posible con la aplicación web siendo completamente pública.
Realmente no quiero implementar OAuth. Probablemente sea excesivo para mis necesidades.
Siento que es posible que no comprenda totalmente HMAC, por lo que agradecería una explicación y cómo podría implementarlo de forma segura con una aplicación web y una aplicación móvil.
Actualizar
Terminé usando HTTP Basic Auth, sin embargo, en lugar de proporcionar el nombre de usuario y la contraseña reales en cada solicitud, se implementó un punto final para intercambiar el nombre de usuario y la contraseña de una clave de acceso que se proporciona para cada solicitud autenticada. Elimina el problema de almacenar el nombre de usuario y la contraseña en el navegador, pero, por supuesto, aún podría pescar la ficha si tenía acceso a la máquina y usarla. En retrospectiva, probablemente habría mirado más a OAuth, pero es bastante complicado para los principiantes.
Deberías usar OAuth2. Aquí es cómo:
1) Aplicación móvil
Las credenciales del cliente de la tienda de aplicaciones móviles como usted mismo. A continuación, utiliza "Concesión de credenciales de contraseña del propietario del recurso" (ver http://tools.ietf.org/html/rfc6749#section-4.3 ) para enviar esas credenciales. A su vez, obtiene un token (portador) que puede usar en las siguientes solicitudes.
2) Sitio web
El sitio web utiliza "Autorización de concesión de código" (ver http://tools.ietf.org/html/rfc6749#section-4.1 ):
El sitio web ve una solicitud no autorizada y redirecciona el navegador al punto final de autorización habilitado para HTML en la API REST.
El usuario se autentica con el servicio REST
El sitio REST redirecciona al usuario al sitio web con el token de acceso en la URL.
El sitio web llama al sitio REST y cambia el token de acceso al token de autorización.
Aquí, después de que el sitio web usa el token de autorización para acceder al servicio REST (en nombre del usuario final), generalmente incluyendo el token como un token "portador" en el encabezado Autorización HTTP.
No es ciencia espacial, pero lleva tiempo comprenderlo por completo.
3) Restringir el acceso API para ciertas aplicaciones
En OAuth2, a cada cliente se le envía una identificación de cliente y un secreto de cliente (en este caso, "cliente" es su aplicación móvil o sitio web). El cliente debe enviar estas credenciales al autorizar. Su servicio REST puede usar esto para validar al cliente que llama
Resolví esto para mi API con bastante facilidad y seguridad sin la necesidad de exponer las credenciales de ningún cliente.
También dividí el problema en 2 partes. Autenticación API: es una solicitud válida de una entidad reconocida (sitio web o aplicación nativa). Autorización de API, es que la entidad puede usar este punto final en particular y el verbo HTTP.
La autorización se codifica en la API mediante una lista de control de acceso y permisos y configuraciones de usuario que se configuran en el código API, la configuración y la base de datos según sea necesario. Una declaración if simple en la API puede probar la autorización y devolver la respuesta adecuada (no autorizada o los resultados del procesamiento de la llamada API).
La autenticación ahora solo se trata de verificar si la llamada es genuina. Para hacer esto, expido certificados autofirmados a los clientes. Se realiza una llamada a la API desde su servidor siempre que lo deseen, generalmente cuando generan su primera página (o cuando están realizando sus propias comprobaciones de inicio de sesión de la aplicación). Esta llamada usa los certificados que he proporcionado previamente. Si, por mi parte, estoy contento de que el certificado sea válido, puedo devolver un nonce y una clave API generada por tiempo limitado. Esta clave se utiliza en todas las llamadas posteriores a otros puntos finales API, en el encabezado de portador, por ejemplo, y se puede almacenar de forma bastante abierta en un campo de formulario HTML o variable de JavaScript o una variable dentro de una aplicación.
El nonce evitará los ataques de repetición y la clave de la API se puede robar si alguien quiere; no podrán continuar utilizando después de que caduque o si el nonce cambia antes de que realicen la próxima llamada.
Cada respuesta de API contendrá el siguiente nonce de si el nonce no coincide, devolverá un error de autenticación. De hecho, el nonce no coincide, también elimino la clave API. Esto obligará a un usuario API genuino a volver a autenticarse utilizando los certificados.
Siempre que el usuario final mantenga esos certificados a salvo y no exponga el método que utiliza para realizar la llamada de autenticación inicial (como hacer una solicitud de Ajax que pueda reproducirse), las API son agradables y seguras.
Una forma de abordar el problema de la autenticación de usuario en la API es solicitando un token de autenticación desde la API cuando el usuario inicia sesión. Este token se puede usar para solicitudes posteriores. Ya has tocado este enfoque, es bastante bueno.
Con respecto a la restricción de ciertas aplicaciones web. Querrá que cada aplicación web se identifique con cada solicitud y que esta autenticación se lleve a cabo dentro de su implementación de API. Muy claro.