android - integrar - oauth2 tutorial
Autenticando con OAuth2 para una aplicaciĆ³n*y*un sitio web (6)
Estoy desarrollando un sitio web al que se accede principalmente a través de una aplicación, y quiero usar OAuth2 para el registro y la autenticación de los usuarios. Como es una aplicación de Android, comenzaré a usar las cosas de OAuth2 de Google, ya que proporciona una interfaz de usuario decente en Android.
Google afirma que "puede optar por utilizar el sistema de autenticación de Google como una forma de externalizar la autenticación de usuario para su aplicación. Esto puede eliminar la necesidad de crear, mantener y proteger un nombre de usuario y una tienda de contraseñas". que es lo que quiero hacer Sin embargo, cuando reviso todos sus ejemplos y otras cosas, solo puedo encontrar información sobre cómo un sitio web o una aplicación autentican a un usuario contra los servicios de Google.
Y, de hecho, cuando voy a registrar mi aplicación ("cliente") con OAuth2 de Google, hay opciones para los clientes del sitio web y los clientes "instalados" (es decir, una aplicación móvil), pero no para ambos. Puedo crear dos clientes por separado, pero leo el borrador de OAuth2 y creo que habrá un problema, que ahora explicaré.
Así es como lo visualicé trabajando:
- El usuario le pide a MyApp que acceda a sus datos privados.
- La aplicación usa la clase
AccountManager
de Android para solicitar un token de acceso para las API de Google. - Android dice al usuario "La aplicación ''MyApp'' quiere acceder a su información básica en Google. ¿Está bien?"
- El usuario dice que sí.
-
AccountManager
conecta al servidor OAuth2 de Google utilizando las credenciales almacenadas en el teléfono y solicita un token de acceso. - Se devuelve el token de acceso (que sigue a las líneas verdes).
-
AccountManager
devuelve el token de acceso a MyApp. - MyApp envía una solicitud a MySite para los datos privados del usuario, incluido el token de acceso.
- MySite necesita verificar al usuario, usando el token de acceso. Valida el token como se describe aquí , con Google: "Google, ¿este token es válido?".
- Ahora, lo que quiero que suceda es que Google dice "Sí, quienquiera que se lo dio es realmente ese usuario", pero lo que realmente creo que sucederá (basado en el borrador de OAuth2 y la documentación de Google) es que dirá "No". ¡ese token solo es válido para MyApp, y tú eres MySite! GTFO! ".
Entonces, ¿cómo debería hacer esto? Y POR FAVOR, no diga "Use OpenID" o "No use OAuth2" u otras respuestas igualmente inútiles. Ah, y realmente me gustaría seguir usando la agradable AccountManager
usuario de AccountManager
lugar de usar WebView
s WebView
.
Editar
La respuesta provisional (¡informaré si funciona!) De Nikolay es que realmente debería funcionar, y a los servidores de Google no les importará de dónde vino el token de acceso. Me parece un poco inseguro, pero veré si funciona.
Actualizar
Implementé este patrón con Facebook en lugar de Google y funciona totalmente. Al servidor OAuth2 no le importa de dónde proviene el token de acceso. Al menos Facebook no, así que supongo que Google tampoco.
A la luz de eso, ¡es una muy mala idea almacenar tokens de acceso! Pero tampoco queremos tener que acceder a los servidores de Facebook / Google para verificar la autenticación de cada solicitud, ya que ralentizará todo. Probablemente, lo mejor es agregar una cookie de autenticación adicional para su sitio que distribuya cuando se valida su token de acceso, pero una forma más simple es tratar el token de acceso como una contraseña y almacenar un hash. Tampoco es necesario que se salde, ya que los tokens de acceso son muy largos. Entonces, los pasos anteriores se convierten en algo así como:
9. MySite necesita verificar al usuario, usando el token de acceso. Primero comprueba su caché de tokens de acceso válidos hash. Si el hash del token se encuentra allí, sabe que el usuario está autenticado. De lo contrario, comprueba con Google como se describe aquí , con Google: "Google, ¿este token es válido?".
10. Si Google dice que el token de acceso no es válido, le decimos al usuario GTFO. De lo contrario, Google dice "Sí, es un usuario válido" y luego verificamos nuestra base de datos de usuarios registrados. Si ese nombre de usuario de Google (o identificación de Facebook si usa Facebook) no se encuentra, podemos crear un nuevo usuario. Luego guardamos en caché el valor hash del token de acceso.
Puede usar el token de acceso recuperado por la aplicación móvil en cualquier otro lugar. Drive SDK tiene una introducción agradable y simple que sigue el flujo en https://developers.google.com/drive/quickstart-android
Probablemente necesite OpenID Connect, que utiliza tokens OAuth para la autenticación. En cuanto a AccountManager
, el soporte actual de OAuth es un poco raro, los nuevos servicios de Google Play , que se lanzarán "pronto", deberían mejorar esto. Vea aquí para una demostración .
describe exactamente lo que desea: https://developers.google.com/identity/protocols/CrossClientAuth
Acabo de publicar una respuesta a una pregunta similar de .
Google llama a estas aplicaciones híbridas y explica cómo una "aplicación de Android obtiene acceso sin conexión para la Web back-end" .
La esencia de esto es que tendrá que pasar una cadena de scope
masajeado a GoogleAuthUtil.getToken
para que devuelva un Código de Autorización (no un Token OAuth2). Ese código de autorización se puede pasar de su aplicación móvil a su servidor y se puede cambiar por un token OAuth2 y un token de actualización, de acuerdo con este esquema .
El parámetro de scope
debe verse de la siguiente manera:
oauth2:server:client_id:<your_server_client_it>:api_scope:<scope_url_1> <scope_url_2> ...
Al menos con Google, el token de acceso finalmente expira. Esta es la razón por la que el AccountManager
android tiene el método invalidateAuthToken
: el token de acceso almacenado en caché ha expirado y debe decirle al AccountManager
que deje de proporcionarle el antiguo y, en su lugar, obtener uno nuevo. Esto hace que sea más seguro almacenar en caché el token, ya que el token en sí no le da acceso eterno como ese usuario. En cambio, cuando es válido, simplemente dice "en algún momento del pasado reciente, este token fue adquirido por una fuente confiable".
Aquí hay un par de cosas que he encontrado útiles al trabajar con tokens. El primero es el punto final tokeninfo de Google. El token en sí es solo JSON codificado en base64. Esto significa que no está encriptado, por lo que debe asegurarse de usar HTTPS para la comunicación. Sin embargo, también significa que puede examinar el token y tener una mejor idea de lo que está sucediendo.
https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=
Si tu token era "abcdef", navegarías a:
https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=abcdef
y Google descomprimiría el token por ti. Es un objeto JSON simple que incluye un campo "expires_in" que le indica el número de segundos durante los cuales el token sigue siendo válido. A las 6:03 en el siguiente video, puedes ver el token desempaquetado:
https://developers.google.com/events/io/sessions/383266187
Ese video incluye una descripción completa de OAuth2 y vale la pena verlo en su totalidad si va a tratar con OAuth y tokens. El hablante también analiza otras formas de tokens Oauth2, que no son tokens de acceso, que no caducan.
Otro recurso útil es el OAuth Playground. Esto le permite hacer cosas básicas como ámbitos de solicitud, solicitudes de recuperación y obtener tokens. Este enlace parece funcionar esporádicamente, y en Chrome tuve que instalar la aplicación Oauth Playground:
https://developers.google.com/oauthplayground/
Y aquí hay un tutorial de Tim Bray, el orador en el video, que explica cómo usar los tokens de acceso para comunicarse con un servidor desde una aplicación de Android. Esto fue útil para mí porque comencé a entender cómo funcionan las cosas diferentes en la Consola API de Google:
http://android-developers.blogspot.in/2013/01/verifying-back-end-calls-from-android.html
Con respecto a la respuesta real a su pregunta, diría que nunca necesita almacenar en caché el token de acceso en el servidor. Como se explicó en el enlace Verificación de llamadas de respaldo desde Android anterior, verificar un token es casi siempre una llamada estática rápida, lo que significa que no hay ninguna razón para almacenar en caché los tokens:
Las bibliotecas pueden almacenar en caché los certificados de Google y solo actualizarlos cuando sea necesario, por lo que la verificación es (casi siempre) una llamada estática rápida.
Finalmente, puedes usar AccountManager
para obtener tokens de acceso. Sin embargo, ahora Google en cambio fomenta el uso de la clase GoogleAuthUtil
en la biblioteca de Servicios de reproducción en su lugar:
En pocas palabras, cuál es la diferencia de usar la solicitud de OAuth2 getAuthToken y getToken
Aquí tenga en cuenta el comentario de Tim Bray, el mismo tipo una vez más de los enlaces anteriores, diciendo que están poniendo sus esfuerzos en la ruta GoogleAuthUtil
. Sin embargo, tenga en cuenta que esto significa que estaría limitado a la autenticación de Google. Creo que el AccountManager
podría usar para obtener, por ejemplo, un token de Facebook en su lugar, no el caso de GoogleAuthUtil
.
Cuando tuvimos la necesidad de hacer algo similar en un servidor OAuth que no sea de Google, guardamos los tokens en un DB en el sitio web. La aplicación luego usaría los servicios web para solicitar el token cuando sea necesario para solicitar datos.
El usuario puede hacer el registro de OAuth en la web o la aplicación. Compartieron el mismo token de aplicación, por lo que podrían compartir el mismo token de acceso. Después del registro, almacenamos los tokens de acceso y actualización en la base de datos para usarlos desde cualquier aplicación que lo necesite.