Récupérer le jeton D'accès Google après authentification par authentification Firebase

j'essaie de récupérer Google Access Token pour accéder à L'API Google REST comme API YouTube Data à partir d'un utilisateur authentifié (en utilisant L'authentification Firebase).

j'ai réussi à intégrer la connexion Google dans mon application avec l'aide de Firebase-INTERFACE utilisateur pour Android - Auth bibliothèque. Le jeton récupéré de FirebaseUser.getToken() la méthode N'est pas un Token D'accès Google valide pour L'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
        }
    }
});

Google Se connecter pour le guide web, c'est possible d'obtenir le jeton d'accès en appelant var token = result.credential.accessToken;, mais je ne peux pas trouver la méthode similaire dans Android.

Toutes les entrées? Veuillez commenter ici si Je ne fournis pas suffisamment d'informations. Je vous remercie :)

28
demandé sur BNK 2016-11-28 09:15:24

3 réponses

La façon dont vous le faites vous donnera firebase id de jeton, voir ici.


il y a trois types de tokens que vous rencontrerez dans firebase :

  • Firebase ID tokens

    créé par Firebase lorsqu'un utilisateur se connecte à une application Firebase. Ces tokens sont des JWTs signés qui identifient en toute sécurité un utilisateur dans un projet Firebase. Ces jetons contiennent des informations de profil de base pour un utilisateur, y compris la chaîne D'identification de l'utilisateur, qui est unique au projet Firebase. Comme l'intégrité des jetons ID peut être vérifiée, vous pouvez les envoyer à un serveur d'arrière-plan pour identifier l'utilisateur actuellement connecté.

  • jetons de fournisseur D'identité

    créé par des fournisseurs d'identité fédérés, tels que Google et Facebook. Ces tokens peuvent avoir différents formats,mais sont souvent des tokens d'accès 2.0. Les applications Firebase utilisent ces tokens pour vérifier que les utilisateurs ont réussi à s'authentifier auprès du fournisseur d'identité, puis à les convertir en justificatifs d'identité utilisables par les services Firebase.

  • Firebase jetons Personnalisés

    créé par votre système d'auth personnalisé pour permettre aux utilisateurs de s'identifier à une application Firebase en utilisant votre système d'auth. Les jetons personnalisés sont des JWT signés en utilisant la clé privée d'un compte de service. Les applications Firebase utilisent ces tokens un peu comme elles utilisent les tokens retournés par federated identity Fournisseur.


maintenant, ce que vous obtenez est un jeton d'identification de base de feu, ce dont vous avez besoin est un jeton de fournisseur D'identité.

simple d'obtenir Fournisseur d'Identité jeton, c'est juste une étape précédente à l'étape que vous avez indiqué.

ainsi, la façon dont nous signons dans google en utilisant firebase est mentionnée ici.

je vais ajouter ci-dessous le code complet qui affiche un bouton dans UI, qui sur cliqué, va signer dans l'utilisateur à compte google. Et puis j'obtiendrai le token d'accès google, qui est ensuite envoyé à firebase, où il est converti en ID de token firebase.

je présume que vous avez configuré l'application android pour vous connecter à google, sinon, vous pouvez entrer dans les détails ici.


(pour raccourcir les choses, regardez L'Étape 5 ci-dessous, si vous avez déjà fait la configuration.)
Code :
  1. configurer Google SignIn et 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. ajouter le bouton de connexion Google à votre application

    <com.google.android.gms.common.SignInButton
        android:id="@+id/sign_in_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    
  3. Définir SignIn Cliquez Sur L'Écouteur

    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. Remplacer OnActivityResult méthode en activité:

    @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. Authentification Firebase Avec 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. dernière étape : écouteurs Auth pour 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);
        }
    }
    

ainsi, votre réponse se trouve dans L'Étape 5, qui était juste avant que vous vous authentifiez à firebase et juste après que vous vous êtes authentifié dans google Se connecter.

j'Espère que ça aide !


mise à jour:

il est important que dans L'Étape 1, vous demandez ID du jeton, sinon à l'Étape 5, vous obtiendrez null Id du jeton. Pour plus d'informations, voir ici. J'ai mis à jour L'Étape 1.


mise à jour:

selon la discussion, le jeton récupéré était JWT comme écrit ici. Et ce dont nous avons besoin est google jeton d'accès. Le code ci-dessous utilise le token JWT pour tirer sur le backend D'OAuth et récupérer ce token d'accès :

(Note : j'ai utilisé okhttp version 2.6.0, d'autres versions peuvent avoir des méthodes différentes)

Code:

...
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();
        }
    }
});

Voici la sortie qui a le token d'accès requis:

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

j'Espère maintenant qu'il contribue à !

35
répondu Abhinav Puri 2016-12-04 07:55:05

GoogleAuthUtil.getTokenportée c'est comme "oauth2:scope1 portée2 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 {
        }
    }
}
18
répondu vovkas 2017-07-04 14:44:37

je suis la solution @vovkas, et je tiens à vous le faire savoir avec la dernière mise à jour 11.6.0 vous pouvez obtenir le Account nécessaire plus facilement, de sorte que vous pouvez avoir tout à l'intérieur d'un handy dandyAsyncTask pour être réutilisée à chaque fois que vous voulez:

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 clé est d'utiliser GoogleSignIn.getLastSignedInAccount(context).

2
répondu cutiko 2017-11-14 19:06:52