2010-07-28 20 views
30

Estoy construyendo un servicio web y me gustaría usar las credenciales de la cuenta de google del usuario.Credenciales de servicios web - OpenID/Android AccountManager?

El servicio se ejecuta en GAE y tendrá un cliente web y un cliente nativo de Android.

Este es mi primer intento de algo así y he estado leyendo sobre OpenID y la biblioteca de Android AccountManager.

Todavía no estoy seguro de cuáles son mis opciones en términos de almacenamiento de los usuarios en mi Datastore. ¿Qué identificador debería usar? ¿Es posible usar OpenID en una aplicación nativa de Android?

Cualquier ayuda y/o sugerencias serán apreciadas. Gracias.

Respuesta

30

Tuvimos unos requisitos similares sobre el último proyecto: backend GAE con GWT frontend y Android/clientes de iPhone. Además, no queríamos almacenar credenciales de usuario.

Así que optamos por utilizar OpenID, que desafortunadamente es un estándar web y no funciona bien con dispositivos móviles, pero es factible.

En el lado GAE simplemente habilitamos el inicio de sesión federado que nos dio OpenID.

En los dispositivos móviles, cuando el usuario necesita iniciar sesión, le presentamos una lista de los autenticadores OpenID (Google, Yahoo, etc.). Luego, abrimos un navegador nativo (no el navegador integrado) y enviamos al usuario al sitio de autenticación de OpenID elegido. La ventaja es que el navegador del usuario generalmente ya tiene el nombre de usuario/contraseña recordado, por lo que este paso solo requiere que el usuario presione un botón.

Todo esto es bastante sencillo. Ahora aquí está la parte difícil: Después de que el usuario confirma el inicio de sesión, OpenID redirecciona a nuestra URL de devolución de GAE (debe proporcionar esta url cuando se solicite). En esta url creamos una URL personalizada, por ejemplo:

yourappname://usrname#XXXYYYZZZ 

donde XXXYYYZZZZ es token de autenticación. Obtenemos este token de la página de devolución donde se almacena como una cookie de ACSID: usamos algunos JSP para leer esta cookie y envolverla en la URL personalizada anterior.

Luego registramos nuestras aplicaciones de Android y iPhone para manejar las URL yourappname://, de modo que cuando el usuario hace clic en este enlace, nuestra aplicación se invoca y el enlace se le pasa. Extraemos el nombre de usuario y el token de este enlace y lo usamos en solicitudes de REST para el back-end de GAE.

Si tiene más preguntas, me gustaría actualizar esta publicación.

Actualización:

La cookie de sesión de usuario en AppEngine producción se llama ACSID, mientras que el servidor de desarrollo de App Engine es llamado dev_appserver_login.

+0

+1 - ¡muy detallado! ¿Qué muestra el texto URL personalizado? "Haga clic aquí para volver a la aplicación"? ¿O algo así? –

+0

Puede mostrar lo que quieras. Utilicé el enlace "Continuar ..." que parece un botón. Con algunos javascript, posiblemente podría iniciar la aplicación automáticamente, sin requerir que el usuario haga clic en el enlace, no lo intentó, necesitaría ser probado. –

0

http://developer.android.com/search.html#q=AccountManager&t=0

http://developer.android.com/resources/samples/SampleSyncAdapter/index.html en la parte inferior de esta página usted encontrará todo el código necesario

mejores deseos

+0

El ejemplo vinculado no usa OpenID o Xauth, por lo que no se puede usar en GAE para autenticarse contra cuentas existentes de Google. Como puedo ver, usa su propio esquema de autenticación: POST simple con nombre de usuario/contraseña como parámetros de encabezado. –

+0

aunque @peterKnego tiene un punto con respecto a la segunda recomendación, el primer enlace es bastante útil. pero estoy de acuerdo en que se debe prestar más atención a la formulación de una respuesta adecuada, fmo. pero tenga cuidado de no ser degradado en el futuro. –

12

Pasé aproximadamente una semana para encontrar una forma adecuada y moderna para esto, sin navegador web y usando el administrador de cuentas de Android.

Si desea utilizar la cuenta de Google y el administrador de cuentas para identificar el usuario puede:

  1. Obtener su contadores a los contactos de Google (auth tipo de token es "CP") a través de administrador de cuentas de fondo hilo :

    public String getUserToken(Activity activity) 
    { 
        AccountManager accountManager = AccountManager.get(activity); 
        AccountManagerFuture<Bundle> amf = accountManager.getAuthTokenByFeatures("com.google", "cp", null, activity, Bundle.EMPTY, Bundle.EMPTY, null, null); 
    
        Bundle bundle = null; 
        try { 
         bundle = amf.getResult(); 
         String name = (String) bundle.get(AccountManager.KEY_ACCOUNT_NAME); 
         String type = (String) bundle.get(AccountManager.KEY_ACCOUNT_TYPE); 
         String token = bundle.getString(AccountManager.KEY_AUTHTOKEN); 
         return token; 
        } catch (OperationCanceledException e) { 
         e.printStackTrace(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } catch (AuthenticatorException e) { 
         e.printStackTrace(); 
        } 
        return null; 
    } 
    
  2. Pass recibieron UserToken al servidor a través asegurado canal.

  3. Validar el token en el servidor de Google usando la biblioteca gdata (Google Data API library):

    public String getUserId(String token) 
    { 
        ContactsService contactsService = new ContactsService("Taxi"); 
        contactsService.setUserToken(token); 
    
        IFeed feed = null; 
        try { 
         feed = contactsService.getFeed(new URL("https://www.google.com/m8/feeds/contacts/default/full?max-results=10000"), ContactFeed.class); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } catch (ServiceException e) { 
         e.printStackTrace(); 
        } catch (NullPointerException e) { 
         e.printStackTrace(); 
        } 
    
        if (feed == null) 
         return null; 
    
        String externalId = feed.getId(); 
        IPerson person = feed.getAuthors().get(0); 
        String email = person.getEmail(); 
        String name = person.getName(); 
        String nameLang = person.getNameLang(); 
    
        return externalId; 
    } 
    
  4. Google testigo puede caducar (por lo general después de una hora), por lo que si usted no pudo validar el token en el servidor , debe enviar una respuesta al cliente, invalidar el token y obtener uno nuevo. Utilizar el gestor de cuenta para invalidar el token:

    public void invalidateUserToken(Context context, String token) 
    { 
        AccountManager accountManager = AccountManager.get(context); 
        accountManager.invalidateAuthToken("com.google", token); 
    } 
    
+0

¿es posible hacer lo mismo (obtener el token que se utilizará) para los mensajes de correo electrónico en gmail y para Facebook? si es así, ¿puede responderla en la siguiente publicación ?: http://stackoverflow.com/questions/11532257/use-syncadapter-to-sync-with-local-gmail-and-facebook-app-data –

+0

Pero eso no Resolver el problema ya que quiere autenticar al usuario en su propio servicio web con una base de datos, supongo, así que si quiere autenticarse en su servicio web, debe enviar el token y su ID de Google en el servicio web y el servicio web debe enviar el token. en el servidor de Google que envía una respuesta con la ID de Google que puede comparar con la ID de Google que el usuario ha enviado, ¿no es así? Cómo haces eso ? – Karly

+1

He probado esta solución y funciona muy bien si solo necesita un correo electrónico autenticado de su usuario. Lo bueno es que puedes hacer todo en tu aplicación sin un navegador web. La desventaja es que debes pedir permiso para editar los contactos de los usuarios, algo que algunos dudan en hacer. ¿Alguien sabe de una manera de simplemente solicitar autenticación sin pedir autorización? – thomas88wp

3

creo this entrada de blog hace exactamente lo que quiere. Funcionó para mí Ambas soluciones publicadas aquí son viables e inteligentes, pero creo que esto es exactamente lo que estaba preguntando el autor de la pregunta.

Básicamente, acaba de obtener un authToken utilizando el ámbito "ah" y pasándolo a la página web correcta para obtener la cookie ACSID que le permitirá acceder a cualquier página de App Engine que use UserService para la autenticación.