17

Currently, I am working on the application where user able to login with Google. As part of the login process, we need to send Google ACCESS TOKEN and REFRESH TOKEN to server end.

I am retrieving access token by the following method,

        mAccountName = googleSignInAccount.getEmail();
        String scopes = "oauth2:profile email";
        String token = null;
        try {
            token = GoogleAuthUtil.getToken(activity.getApplicationContext(), mAccountName, scopes);
        } catch (IOException e) {
            Logger.eLog(TAG, e.getMessage());
        }

GoogleAuthUtil class from which I am accessing access token don't have a function for refresh token. So how to access Refresh Token? Thanks in advance!

Swapnil Sonar
  • 2,232
  • 2
  • 29
  • 42

2 Answers2

10

You should use the server auth code flow via Auth.GOOGLE_SIGN_IN_API: get an server auth code on Android client, send to your server, server exchanges the code for refresh and access token (with a secret). There are more details in this blog post as well.

Also, if you are using GoogleAuthUtil.getToken for access token now, you do want to check out this Google Sign-In best practice blog post to see how to migrate to the recommended flow to ensure security and best UX.

Isabella Chen
  • 2,421
  • 13
  • 25
  • Could you halp me, when i use this method i can't provide to user pop-up to choose accaunt... When user click to Log In , occur logIn with current device accautn... User can't change any think... How can i provide to user pop-up with accounts? – Sirop4ik Aug 09 '16 at 08:00
  • @AlekseyTimoshchenko If you: a) once signed an account in on this device, sign-in library will remember the account for you and auto-use that account in future sign-ins b) have multiple accounts on the device and only one of them has authorized to all the scopes, cross-device-single-sign-on will take effect and auto sign that one account in.. If you are right now in that state, you can go to Settings->Connected Apps to revoke access and then you can see account chooser again. – Isabella Chen Aug 20 '16 at 01:39
  • Hi @IsabellaChen, do you think that `GoogleAuthUtil.getToken` can be used for [this question](http://stackoverflow.com/questions/40838154/retrieve-google-access-token-after-authenticated-using-firebase-authentication)? – BNK Dec 08 '16 at 04:50
  • @BNK, no, you should never use GoogleAuthUtil. Use Auth.GOOGLE_SIGN_IN_API and server auth code flow described in below doc:https://developers.google.com/identity/sign-in/android/offline-access and also this particular blog post: http://android-developers.blogspot.com/2016/02/using-credentials-between-your-server.html. – Isabella Chen Dec 09 '16 at 06:33
  • @IsabellaChen I know that flow already, just because I haven't ever used `GoogleAuthUtil.getToken` before :) – BNK Dec 09 '16 at 06:38
  • @BNK,GoogleAuthUtil is also kinda legacy. The only reason it's still there is for rare cases like non-REST communications with Google server on Android device (e.g. SASL XOAUTH2 with Gmail). For other use cases, e.g. REST API access on Android, there's library which keeps OAuth token transparent to you, or native Google Play services APIs; server authN / authZ, Auth.GOOGLE_SIGN_IN_API. – Isabella Chen Dec 09 '16 at 08:15
  • @IsabellaChen from [your blogspot](http://android-developers.blogspot.com/2016/05/improving-security-and-user-experience.html) I have found the content `In general, you should NOT use GoogleAuthUtil.getToken, unless you are making REST API call on Android client.` at the end. If I understand it correctly, you did not mention non-REST communications – BNK Dec 09 '16 at 08:20
  • 2
    @BNK, I could not exhaust all use cases, so just called out most common use case (v.s. server access) REST API access with transparent OAuth token (library support and documentation) is still in progress. At the time of the blog post, GoogleAuthUtil was still the officially documented approach for making REST API calls on Android. – Isabella Chen Dec 10 '16 at 00:54
1

I think you need to try this code in AsyncTask like below.

private class RetrieveTokenTask extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        String accountName = params[0];
        String scopes = "oauth2:profile email";
        String token = null;
        try {
            token = GoogleAuthUtil.getToken(getApplicationContext(), accountName, scopes);
        } catch (IOException e) {
            Log.e(TAG, e.getMessage());
        } catch (UserRecoverableAuthException e) {
            startActivityForResult(e.getIntent(), REQ_SIGN_IN_REQUIRED);
    //REQ_SIGN_IN_REQUIRED = 55664;
        } catch (GoogleAuthException e) {
            Log.e(TAG, e.getMessage());
        }
        return token;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        Log.i("AccessToken",s);
    }
}

Then call AsyncTask like below to get Access Token:

...    
new RetrieveTokenTask().execute(mAccountName);

Check here. I hope it's help you.

pRaNaY
  • 24,642
  • 24
  • 96
  • 146
  • Thanks Pranay! I am looking for a refresh token. I got access token already with similar kind of implementation. – Swapnil Sonar Feb 02 '16 at 14:39
  • 6
    you can look at [this issue](http://stackoverflow.com/questions/26969622/how-to-get-refreshtoken-when-using-googleauthutil). It indicates that you can't get a refresh token using `GoogleAuthUtil.getToken()`, but once the token itself in invalidated, it will return a new one (the refresh token) – adjuremods Feb 03 '16 at 00:17