Recuperar Token de Google Access después de autenticado mediante la autenticación de Firebase

Estoy intentando recuperar Token de Google Access para acceder a la API de REST de Google, como la API de datos de YouTube de un usuario autenticado (mediante la autenticación Firebase).

He integrado correctamente el inicio de sesión de Google en mi aplicación con la ayuda de Firebase-UI para Android – Biblioteca de Auth . El token recuperado del método FirebaseUser.getToken() no es un token válido de Google Access para REST API.

 user.getToken(true).addOnCompleteListener(new OnCompleteListener<GetTokenResult>() { public void onComplete(@NonNull Task<GetTokenResult> task) { if (task.isSuccessful()) { String token = task.getResult().getToken(); // 'token' is not a Google Access Token } } }); 

En la guía de var token = result.credential.accessToken; sesión de Google para Web , es posible obtener el token de acceso llamando a var token = result.credential.accessToken; , Pero no puedo encontrar el método similar en Android.

¿Entradas? Por favor comente aquí si no proveo suficiente información. Gracias 🙂

La forma en que estás haciendo te dará el token de ID de firebase, mira aquí .


Hay tres tipos de fichas que encontrarás en firebase:

  • Fichas ID Firebase

    Creado por Firebase cuando un usuario inicia sesión en una aplicación de Firebase. Estos tokens son JWTs firmados que identifican de forma segura a un usuario en un proyecto de Firebase. Estos tokens contienen información de perfil básica para un usuario, incluida la cadena de ID del usuario, que es exclusiva del proyecto Firebase. Dado que se puede verificar la integridad de los tokens de ID, puede enviarlos a un servidor back-end para identificar al usuario que ha iniciado sesión actualmente.

  • Fichas de proveedores de identidad

    Creado por proveedores de identidad federados, como Google y Facebook. Estos tokens pueden tener diferentes formatos, pero a menudo son fichas de acceso de OAuth 2.0. Las aplicaciones de Firebase utilizan estos tokens para verificar que los usuarios se han autenticado correctamente con el proveedor de identidad y, a continuación, convertirlos en credenciales utilizables por los servicios de Firebase.

  • Ficheros personalizados Firebase

    Creado por su sistema de autenticación personalizado para permitir a los usuarios iniciar sesión en una aplicación de Firebase utilizando su sistema de autenticación. Los tokens personalizados son JWTs firmados mediante la clave privada de una cuenta de servicio. Las aplicaciones de Firebase utilizan estos tokens de la misma forma que utilizan los tokens devueltos por los proveedores de identidad federados.


Ahora, lo que obtienes es un token de ID de firebase, lo que necesitas es Token de Proveedor de Identidad.

Su simple para obtener el token de proveedor de identidad, es sólo un paso anterior al paso que ha mostrado.

Por lo tanto, la forma en que firmar en google con firebase se menciona aquí .

A continuación, añadiré el código completo que muestra un botón en la interfaz de usuario, que al hacer clic, se iniciará en el usuario de cuenta de google. Y luego voy a obtener el token de acceso de google, que luego se envía a firebase, donde se convierte en firebase token Id.

Supongo que has configurado la aplicación de Android para que Google inicie sesión, si no, puedes entrar en detalles aquí .


(Para acortar las cosas, solo mira el Paso 5, si ya has hecho la configuración.)


Código :

  1. Configurar Google SignIn y GoogleApiClient :

      // Configure sign-in to request the user's ID, email address, and basic // profile. ID and basic profile are included in DEFAULT_SIGN_IN. GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken(getString(R.string.default_web_client_id)) .requestEmail() .build(); // NOTE : // The string passed to requestIdToken, default_web_client_id, // can be obtained from credentials page (https://console.developers.google.com/apis/credentials). // There mentioned Web application type client ID is this string. // ... // Build a GoogleApiClient with access to the Google Sign-In API and the // options specified by gso. mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this /* Activity */, this /* OnConnectionFailedListener */) .addApi(Auth.GOOGLE_SIGN_IN_API, gso) .build(); 
  2. Agregar el botón de inicio de sesión de Google a tu aplicación

     <com.google.android.gms.common.SignInButton android:id="@+id/sign_in_button" android:layout_width="wrap_content" android:layout_height="wrap_content" /> 
  3. Establecer inicio de sesión de inicio de sesión

     findViewById(R.id.sign_in_button).setOnClickListener(new OnClickListener() { public void onClick(View v){ Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); startActivityForResult(signInIntent, RC_SIGN_IN); } }); 
  4. Anular método OnActivityResult en Actividad :

     @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...); if (requestCode == RC_SIGN_IN) { // Google Sign In was successful, authenticate with Firebase GoogleSignInAccount account = result.getSignInAccount(); firebaseAuthWithGoogle(account); // This method is implemented in step 5. } else { // Google Sign In failed, update UI appropriately // ... } } 
  5. Autenticación de Firebase con Google SignInAccount

     String idTokenString = ""; ... private void firebaseAuthWithGoogle(GoogleSignInAccount acct) { Log.d(TAG, "Google User Id :" + acct.getId()); // --------------------------------- // // BELOW LINE GIVES YOU JSON WEB TOKEN, (USED TO GET ACCESS TOKEN) : Log.d(TAG, "Google JWT : " + acct.getIdToken()); // --------------------------------- // // Save this JWT in global String : idTokenString = acct.getIdToken(); AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null); mAuth.signInWithCredential(credential) .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { Log.d(TAG, "signInWithCredential:onComplete:" + task.isSuccessful()); if(task.isSuccessful()){ // --------------------------------- // // BELOW LINE GIVES YOU FIREBASE TOKEN ID : Log.d(TAG, "Firebase User Access Token : " + task.getResult().getToken()); // --------------------------------- // } // If sign in fails, display a message to the user. If sign in succeeds // the auth state listener will be notified and logic to handle the // signed in user can be handled in the listener. else { Log.w(TAG, "signInWithCredential", task.getException()); Toast.makeText(GoogleSignInActivity.this, "Authentication failed.", Toast.LENGTH_SHORT).show(); } } }); } 
  6. Paso final: Auditores Auth para Firebase

     private FirebaseAuth mAuth; private FirebaseAuth.AuthStateListener mAuthListener; @Override protected void onCreate(Bundle savedInstanceState) { // ... mAuth = FirebaseAuth.getInstance(); mAuthListener = new FirebaseAuth.AuthStateListener() { @Override public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { FirebaseUser user = firebaseAuth.getCurrentUser(); if (user != null) { // User is signed in Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid()); } else { // User is signed out Log.d(TAG, "onAuthStateChanged:signed_out"); } // ... } }; // ... } //... @Override public void onStart() { super.onStart(); mAuth.addAuthStateListener(mAuthListener); } @Override public void onStop() { super.onStop(); if (mAuthListener != null) { mAuth.removeAuthStateListener(mAuthListener); } } 

Por lo tanto, su respuesta se encuentra en el Paso 5, que fue justo antes de que se autenticó a firebase y justo después de que usted autenticado en google inicio de sesión.

Espero eso ayude !


ACTUALIZACIÓN:

Es importante que en el paso 1, solicite Id de token, de lo contrario en el paso 5, obtendrá id de token nulo. Para más ver aquí . He actualizado el Paso 1.


ACTUALIZACIÓN:

Según la discusión, el token recuperado fue token JWT como se escribe aquí . Y lo que necesitamos es Token de acceso de Google. El código inferior usa el token JWT para disparar en el backend OAuth y recuperar este token de acceso:

(Nota: he utilizado okhttp versión 2.6.0, otras versiones pueden tener diferentes métodos)

Código:

 ... OkHttpClient client = new OkHttpClient(); RequestBody requestBody = new FormEncodingBuilder() .add("grant_type", "authorization_code") .add("client_id", "<Your-client-id>") // something like : ...apps.googleusercontent.com .add("client_secret", "{Your-client-secret}") .add("redirect_uri","") .add("code", "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8") // device code. .add("id_token", idTokenString) // This is what we received in Step 5, the jwt token. .build(); final Request request = new Request.Builder() .url("https://www.googleapis.com/oauth2/v4/token") .post(requestBody) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(final Request request, final IOException e) { Log.e(LOG_TAG, e.toString()); } @Override public void onResponse(Response response) throws IOException { try { JSONObject jsonObject = new JSONObject(response.body().string()); final String message = jsonObject.toString(5); Log.i(LOG_TAG, message); } catch (JSONException e) { e.printStackTrace(); } } }); 

Aquí está la salida que tiene token de acceso como se requiere:

 I/onResponse: { "expires_in": 3600, "token_type": "Bearer", "refresh_token": "1\/xz1eb0XU3....nxoALEVQ", "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjQxMWY1Ym......yWVsUA", "access_token": "ya29.bQKKYah-........_tkt980_qAGIo9yeWEG4" } 

Espero que ahora ayuda!

Pruebe GoogleAuthUtil.getToken donde el ámbito es como "oauth2: scope1 scope2 scope3"

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken(getString(R.string.default_web_client_id)) .requestEmail() .build(); mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this, this) .addApi(Auth.GOOGLE_SIGN_IN_API, gso) .build(); } private void signIn() { Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); startActivityForResult(signInIntent, RC_SIGN_IN); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RC_SIGN_IN) { GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); if (result.isSuccess()) { final GoogleSignInAccount account = result.getSignInAccount(); Runnable runnable = new Runnable() { @Override public void run() { try { String scope = "oauth2:"+Scopes.EMAIL+" "+ Scopes.PROFILE; String accessToken = GoogleAuthUtil.getToken(getApplicationContext(), account.getAccount(), scope, new Bundle()); Log.d(TAG, "accessToken:"+accessToken); //accessToken:ya29.Gl... } catch (IOException e) { e.printStackTrace(); } catch (GoogleAuthException e) { e.printStackTrace(); } } }; AsyncTask.execute(runnable); } else { } } } 
  • No se puede resolver el símbolo 'Auth' para la integración de Google en android studio
  • No se puede establecer el ámbito de acceso de Google en Android
  • Signin de Google Firebase dando estado 12501 (no funciona), en la versión de creación de la versión y jks SHA
  • Android: ¿Cómo obtener un token de actualización mediante Google Sign-In API?
  • Android Auth Error: "GetToken falló con el código de estado: INVALID_AUDIENCE"
  • ¿Cómo obtener un perfil como género de google signin en Android?
  • ¿Inicia sesión de Google no funciona en Android?
  • La ejecución falló para la tarea ': app: transformClassesWithDexForDebug' al implementar Google inicie sesión en Android
  • Se requiere la autenticación de Google con un servidor de back-end
  • Deprecated Plus.PeopleApi.load
  • GoogleApiClient tiene un Plus.API opcional y no está conectado a Plus con el nuevo signo de Google introducido en Play Services 8.3
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.