node.js - metodo - token encriptado
La forma "correcta" de hacer OAuth desde un cliente móvil (2)
Estoy construyendo una aplicación móvil multiplataforma (usando las herramientas Xamarian, MonoTouch / MonoDroid). Estoy tratando de trabajar en el flujo de trabajo de autenticación y me estoy tropezando. He buscado por todas partes una respuesta clara y todavía tengo que encontrarla.
Aquí hay una descripción general de mi configuración actual.
Tengo un sitio web creado en nodejs. Yo uso passport.js para hacer login de OAuth en el sitio web. Esto funciona muy bien, los usuarios pueden iniciar sesión en mi sitio usando Twitter o Facebook.
Ahora quiero extender esta misma funcionalidad de inicio de sesión a mis clientes móviles.
Veo 2 opciones
Incruste los id de la aplicación y los secretos de la aplicación en los clientes de dispositivos móviles y realice llamadas directas de OAuth a FB o Twitter desde la aplicación móvil.
Proxy las llamadas oAuth a través de mi servidor web nodejs existente (manteniendo las claves secretas en el servidor)
La opción 2 parece ser la preferida (ya que evita tener que "enviar" el secreto en las aplicaciones móviles).
Tengo el enfoque de proxy funcionando principalmente.
- Abrí un WebView en mi cliente móvil y lo
http://mysever/auth/twitter
enhttp://mysever/auth/twitter
- Esto se ejecuta a través de mi código passport.js existente y redirige el WebView móvil a la página de inicio de sesión de Twitter.
- El usuario ingresa sus credos en la página web de Twitter en el dispositivo.
- Twitter luego llama a mi URL de devolución de OAuth (que es el servidor web de mi nodo).
- Mi servidor y Twitter manejan la cuarta mano de la obtención de la información del perfil del usuario ( Según entiendo, esta es la clave de este enfoque, mi servidor y Twitter manejan el apretón de manos, el cliente móvil no tiene que hacer nada ni aprobar cualquier token durante este proceso )
Aquí está mi problema :
Es este último paso el que me detiene. Una vez que se completa el intercambio de información en mi servidor, tengo la información del usuario que necesito en el servidor y necesito enviarla de vuelta a la aplicación del cliente móvil.
No puedo encontrar ningún modo en el control WebView para tomar el objeto de respuesta y tomar una cookie o valor de encabezado (por ejemplo) (esto parece cierto para Android e iOS). No creo que sea específico de la plataforma. Creo que estoy tratando de hacer algo que un widget WebView en plataformas móviles simplemente no admite. Me hace pensar que me estoy perdiendo algo obvio.
Lo único que he descubierto es hacer que mi servidor web "redirija" el navegador del cliente móvil a una URL falsa que tiene la información del usuario en la cadena de consulta. Algo así como myapp: // info? Userid = 1234
Luego, en la aplicación móvil, puedo secuestrar la carga de URL y tomar esta URL y obtener los datos que necesito. A continuación, puedo guardar esta información de usuario, cerrar el control WebView y pasar a una pantalla nativa en mi aplicación móvil y utilizar la información de usuario en cualquier llamada REST posterior al servidor de mi nodo como un medio para identificar al usuario.
Esto es masivamente kludgy por múltiples razones. El mayor de ellos es que la URL se envía sin cifrar y tiene todos los datos en texto sin formato.
Tiene que haber una mejor manera de volver a enviar los datos del servidor web al cliente móvil?
¿O estoy haciendo todo mal?
La forma más directa de implementar Oauth para Xamarin, tanto para iOS como para Android, es usar Xamarin.Auth . La documentación inicial para el cliente está aquí . Creo que debería mantener todo de forma segura y no tendrá que preocuparse de tener que usar su servidor de nodo como proxy.
Tendrá que proporcionar su ID de aplicación como parte de las llamadas, pero no hay demasiados problemas de seguridad de los que preocuparse.
Sé que esto va en contra de lo que ya has implementado, pero tal vez esto podría ayudar a simplificar las cosas un poco.
Este es el mismo dilema con el que he estado tratando. Así es como lo trato actualmente. En mi aplicación, el cliente puede venir directamente o a través de otro servicio, como Facebook, que es el principal y, por lo tanto, el que me he concentrado.
Facebook puede redirigir a través de un POST (aplicaciones de escritorio) o un GET (móvil).
Compruebo la solicitud inicial para ver si tiene un identificador de servicio; aquí está el GET de Facebook, por ejemplo.
app.get(''/'', function(req, res) {
var paraUrl = URL.parse(req.url,true).query;
//The fb_source is shown -
//i need to go striaght to the facebook authorization since
//its coming from
//from a mobile device.
if (paraUrl.fb_source){
res.redirect(''/auth/facebook''); //this is the passport part
return;
}
res.sendfile(''index.html'');
}
El POST de Facebook es ligeramente diferente en cuanto a que obtienes una codificación de token de acceso en base64url. El GET te da un código que puedes intercambiar por un token de acceso pero tuve problemas con él y simplemente opté por vincularlo al sistema de pasaportes.
Si un cliente viene directamente, reviso la sesión o una cookie cifrada que se vincula con la estrategia local. Esto comprueba el db para obtener un token de acceso que se puede utilizar para acceder a la API de Facebook, por ejemplo.
Si un cliente no es reconocido, se le da la opción de autenticarse a través de Facebook, google, etc.
Lo principal es que solo se almacenan 2 datos con el cliente, el ID de la sesión del pasaporte y el ID de usuario de mi aplicación
connect.sid - cookie encypted
userId - cookie encypted
Me interesaría saber cómo otras personas están lidiando con un problema