sesion - login firebase android studio
Recupere el token de acceso de Google despuĆ©s de autenticarse utilizando la autenticaciĆ³n Firebase (3)
Estoy intentando recuperar el token de acceso de Google para acceder a la API REST de Google, como la API de datos de YouTube, de un usuario autenticado (mediante la autenticación Firebase).
He integrado con éxito Google Sign-In en mi aplicación con la ayuda de Firebase-UI para Android - Biblioteca de autenticación . El token recuperado del método FirebaseUser.getToken()
no es un token válido de Google Access para la API REST.
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.
Cualquier entrada? Por favor comente aquí si no proporciono suficiente información. Gracias :)
Estoy siguiendo la solución @vovkas, y quiero hacerle saber que con la última actualización 11.6.0
puede obtener la Account
necesita con mayor facilidad, de modo que puede tener todo dentro de una práctica AsyncTask
dandy para ser reutilizada cuando desee:
public class GetToken extends AsyncTask<Void, Void, String> {
private final Context context;
public GetToken(Context context) {
this.context = context;
}
@Override
protected String doInBackground(Void... voids) {
try {
String scope = "oauth2:" + Scopes.EMAIL + " " + Scopes.PROFILE;
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(context);
return GoogleAuthUtil.getToken(context, account.getAccount(), scope, new Bundle());
} catch (IOException e) {
e.printStackTrace();
} catch (GoogleAuthException e) {
e.printStackTrace();
}
return null;
}
}
La clave es usar GoogleSignIn.getLastSignedInAccount(context)
.
La forma en que lo está haciendo le dará el token de identificación de base de fuego, consulte here .
Hay tres tipos de fichas que encontrarás en Firebase:
Fichas de identificación de Firebase
Creado por Firebase cuando un usuario inicia sesión en una aplicación Firebase. Estos tokens son JWT firmados que identifican de forma segura a un usuario en un proyecto 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. Debido a que se puede verificar la integridad de los tokens de ID, puede enviarlos a un servidor backend para identificar al usuario que ha iniciado sesión actualmente.
Fichas de proveedor de identidad
Creado por proveedores de identidad federados, como Google y Facebook. Estos tokens pueden tener diferentes formatos, pero a menudo son tokens de acceso OAuth 2.0. Las aplicaciones de Firebase usan estos tokens para verificar que los usuarios se hayan autenticado correctamente con el proveedor de identidad y luego los conviertan en credenciales que puedan utilizar los servicios de Firebase.
Fichas personalizadas de Firebase
Creado por su sistema de autenticación personalizado para permitir a los usuarios iniciar sesión en una aplicación Firebase utilizando su sistema de autenticación. Los tokens personalizados son JWT firmados con la clave privada de una cuenta de servicio. Las aplicaciones de Firebase usan estos tokens de la misma manera que usan los tokens devueltos por los proveedores de identidad federados.
Ahora, lo que está obteniendo es el token de identificación de base de fuego, lo que necesita es el token de proveedor de identidad.
Es fácil obtener el token del proveedor de identidad, es solo un paso previo al paso que has mostrado.
Por lo tanto, la forma en que iniciamos sesión en google utilizando firebase se menciona here .
Agregaré a continuación el código completo que muestra un botón en la IU, que al hacer clic, iniciará sesión en la cuenta de Google. Y luego obtendré el token de acceso de Google, que luego se envía a firebase, donde se convierte en el ID de token de firebase.
Supongo que ha configurado la aplicación de Android para el inicio de sesión de Google, si no, puede entrar en detalles here .
(Para abreviar, solo mire el Paso 5 a continuación, si ya ha realizado la configuración). Código :Configure 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();
Agregue el botón de inicio de sesión de Google a su aplicación
<com.google.android.gms.common.SignInButton android:id="@+id/sign_in_button" android:layout_width="wrap_content" android:layout_height="wrap_content" />
Set SignIn Click Listener
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); } });
OnActivityResult
métodoOnActivityResult
en la 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: Autores de escucha 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); } }
Entonces, su respuesta se encuentra en el Paso 5, que fue justo antes de que usted se autentique en firebase y justo después de que se haya autentificado en google.
Espero eso ayude !
ACTUALIZACIÓN:
Es importante que en el Paso 1, solicite el ID de token, de lo contrario, en el Paso 5, obtendrá un ID de token nulo. Para más información ver here . He actualizado el paso 1.
ACTUALIZACIÓN:
Según la discusión, el token recuperado era el token JWT como se escribió here . Y lo que necesitamos es token de acceso de Google. El código de abajo utiliza el token JWT para disparar en el backend de OAuth y recuperar este token de acceso:
(Nota: He usado la versión 2.6.0 de okhttp, 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 el 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 ayude!
Pruebe GoogleAuthUtil.getToken donde scope 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 {
}
}
}