Diseño para la autenticación de Facebook en una aplicación de iOS que también accede a un servicio web seguro
Frecuentes
Visto 48,165 veces
409
Meta: Permitir que un usuario se autentique con Facebook en una aplicación de iOS que requiere acceso a un servicio web protegido que estoy ejecutando.
Supuestos: Existe un sistema de autenticación (y registro) nativo para aquellos usuarios que optan por no usar Facebook para iniciar sesión.
Detalles:
- Supongamos que queremos ofrecer la opción de que un usuario inicie sesión con Facebook sin crear una cuenta / credencial separada para nuestro sistema.
- Debido a que admitimos nuestro propio mecanismo de autenticación nativo (nombre de usuario y contraseña), tenemos nuestras propias ID de usuario y emitimos un token de autenticación que se usa para interacciones posteriores después de la validación inicial de credenciales.
Me sorprende que Facebook no tenga las mejores prácticas para esto en su documentación para desarrolladores. Toda la documentación existente asume que está integrando la autenticación de FB en un sitio web o una aplicación móvil independiente sin servicio que requiera autenticación.
Aquí están mis pensamientos iniciales sobre cómo se diseñaría esto, pero quiero validación sobre si es correcto.
- El cliente abre el inicio de sesión de Facebook iOS
- El usuario de la interfaz de usuario inicia sesión con las credenciales de Facebook y obtiene el token de acceso
- La aplicación iOS pasa el token de acceso a nuestro servidor
Nuestro servidor habla con la API de gráficos de FB utilizando el token de acceso para (a) validar el token y (b) obtener el ID de usuario de FB para ese token de acceso.
por ejemplo, nuestro servidor llamaría https://graph.facebook.com/me/?access_token=XYZ que devolvería información de perfil en un objeto JSON
Suponiendo que sea válido, nuestro servidor extrae el ID de usuario del objeto JSON y comprueba si el usuario ya tiene una cuenta. Si es así, emitimos nuestro propio ticket de autenticación al cliente para que lo utilice en esa sesión. Si el usuario no tiene una cuenta, creamos una nueva con el ID de usuario de Facebook, asignamos nuestro propio ID de usuario único y emitimos nuestro ticket de autenticación.
- Luego, el cliente devuelve el vale de autenticación en interacciones posteriores que necesitan autenticación.
Este parece ser el enfoque correcto para mí, pero no estoy seguro de si me estoy perdiendo algo increíblemente básico y voy por el camino equivocado (complicado).
4 Respuestas
83
Acabo de lidiar con esto yo mismo, y aquí está la parte que me mordió:
En su paso 5 ... Es posible que un usuario se registre para una cuenta con usted completamente separada de su ID de Facebook, ¿verdad? Luego, en otra ocasión, inician sesión con Facebook ... Y les acabas de crear una segunda cuenta y pierdes la primera.
Debe haber una forma de iniciar sesión en su servicio web, luego iniciar sesión en Facebook y capturar la asociación entre la identificación de Facebook y la cuenta local.
Aparte de eso, su plan suena sólido.
Actualizar: Facebook ha agregado un documento que describe tal escenario AQUÍ
Respondido 17 Jul 18, 18:07
Sí, lo he considerado y has acertado. Planeamos fusionar cuentas si es la misma dirección de correo electrónico, y si no, crearemos otra forma de fusionarlas. - TMC
¿Qué biblioteca de servidor está utilizando en el lado del servidor para realizar la solicitud? - Tim Leung
@TimLeung: tengo entendido que un token de acceso incorpora la ID de la aplicación y que no puede tener un token de acceso SIN una ID de la aplicación incorporada. - dan ray
@TimLeunge: Estamos usando la API Graph para solicitudes con el token de acceso del usuario. - TMC
30
Use https para transmitir el token de autenticación a su servidor, como lo indica Facebook
Compartir tokens de acceso
Nuestras políticas de datos prohíben explícitamente compartir un token de acceso para su aplicación con cualquier otra aplicación. Sin embargo, permitimos que los desarrolladores compartan tokens entre una implementación nativa y una implementación de servidor de la misma aplicación (es decir, utilizando el mismo ID de aplicación) siempre que la transferencia se realice mediante HTTPS.
respondido 11 mar '13, 03:03
16
Un problema que puedo ver con esta estrategia es que alguien puede darte un token de acceso obtenido para una aplicación de Facebook diferente. Hasta donde yo sé, no hay forma de verificar que el token de acceso sea para su aplicación, así que continuará y lo usará.
Sin embargo, no suena muy dañino. Generalmente, las personas / aplicaciones intentan proteger los tokens de acceso, en lugar de compartirlos.
Una posible explotación de esto sería que alguien creara su propio sitio o aplicación móvil, obtuviera tokens de acceso para sus usuarios e intentara autenticarlos utilizando su API. Si esto tiene éxito (el usuario tiene una cuenta de Facebook en su sitio), el sitio malicioso podrá usar su API haciéndose pasar por el usuario.
Es un poco arriesgado, pero creo que podría funcionar.
Editar: parece que hay una forma de validar el token de acceso después de todo. Vea la respuesta de @Daaniel a la pregunta Obtenga la identificación de la aplicación del token de acceso del usuario (o verifique la aplicación de origen para un token).
contestado el 23 de mayo de 17 a las 12:05
@Tony, ¿puedes explicar cómo? appsecret_proof
ayuda aquí? Por lo que tengo entendido, sirve para demostrarle a Facebook que el servidor conoce la clave secreta. Sin embargo, ivant se refería a una aplicación maliciosa que obtiene tokens y luego los envía a su API. El servidor puede verificar el ID de la aplicación, pero una aplicación maliciosa puede falsificarlo fácilmente. Entonces ... ¿cómo mitigar esto? - YSKMás
Puede verificar que el token se generó para su aplicación a través de https://graph.facebook.com/app/?access_token=[user_access_token]
que devuelve el ID de la aplicación y luego compara los ID de la aplicación - nader alexan
4
tu solución funciona totalmente.
Tal vez una alternativa: ¿por qué no recibir el correo electrónico del cliente desde la solicitud inicial del servicio social y enviarlo a su servicio web? El servicio web podría simplemente almacenar el correo electrónico y tal vez también un proveedor social. Entiendo que su servicio web no podrá validar el origen del correo electrónico, pero ¿no existe una relación de alta confianza entre su servicio web y su cliente? Si lo hay, parece que puede depender de que el correo electrónico provenga del lugar correcto. Alguien, por favor, hágame saber qué cosa obvia me estoy perdiendo que hace que el enfoque basado en correo electrónico sea tonto ...
respondido 04 mar '14, 05:03
Podría averiguar fácilmente cómo el cliente está hablando con el servidor. Entonces podría simplemente lanzarle correos electrónicos hasta que obtenga una respuesta. Siempre debe haber alguna forma de verificación: Chris
¿Alta confianza y cliente? Nunca en la misma oración, por favor. Excepto frase anterior por supuesto. - EralpB
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas ios ios4 facebook facebook-graph-api or haz tu propia pregunta.
¿Cómo se resolvió esto? También estoy buscando pasar el token de acceso y activar al usuario en el servidor. Parece académico, pero estoy preguntando. - Chris Van Buskirk
Esta fue mi implementación usando rieles y diseño: stackoverflow.com/questions/7232490/… - Matt
¿Por qué no pasar todo el auth_hash en lugar de tener que hacer dos llamadas a la API de FB (una desde el dispositivo iOS y otra desde el servidor)? - bsiddiqui
¿Qué sucede si desea iniciar sesión desde un dispositivo diferente (lo que significa que no tiene su boleto de autenticación)? Y si acaba de recibir un nuevo ticket de autenticación, ¿qué impide que alguien se apropie de la identificación / token de Facebook en el camino y lo use en su propio dispositivo? - Amitloaf
Por curiosidad, en el paso 5, ¿por qué emitir su propio ticket de autorización? ¿No podría usar el token de acceso de Facebook para cada llamada posterior al servidor? Me doy cuenta de que requeriría una llamada desde el servidor a la API de Facebook para cada aplicación -> llamada al servidor en lugar de solo la primera. - Anders