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.
- Cómo obtener el botón predeterminado de Google+ en la aplicación de Android
- El inicio de sesión de Google no funciona después de publicarse en la tienda de juegos
- Cómo configurar el texto del cuadro de diálogo de google api en el idioma predeterminado de la aplicación
- Código de estado 12501 autenticando con inicio de sesión de Google
- Compruebe si el usuario ya ha iniciado sesión utilizando Auth.GoogleSignInApi?
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 🙂
- Archivo de configuración de inicio de sesión de Google para varios desarrolladores
- Uid de firewall y firebase uid no coinciden después de actualizar firebase a 9.2.0
- ¿Cómo obtener el token de acceso con el nuevo inicio de sesión de Google con los servicios de juego 8.3?
- Iniciar sesión en Google no funciona
- Google api gettoken (Context, String, String) ahora está obsoleto
- ¿Cómo verificar correctamente la integridad de un token de Google?
- "GoogleApiClient no está conectado todavía" al cerrar la sesión cuando se utiliza la autorización de Firebase con google inicie sesión
- Android Google SignIn no funciona en modo de depuración: GoogleSignInResult es falso
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 :
-
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();
-
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" />
-
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); } });
-
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 // ... } }
-
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(); } } }); }
-
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 { } } }
- Detectar la orientación de la barra de navegación de Android
- Android Fatal Error – No se puede realizar esta acción después de onSaveInstanceState