0

Following https://developers.google.com/identity/sign-in/web/server-side-flow After getting the authorization code from JavaScript, and passing it to the server side, we indeed get an access token (and an ID token), but not the required refresh token.

There are many posts around but could not solve it yet.

Any suggestion how to get the refresh token?

thanks!

    private String getResponseToken(GoogleClientSecrets clientSecrets,
                                                 String authCode) throws IOException {
        try {
            GoogleTokenResponse tokenResponse =
                    new GoogleAuthorizationCodeTokenRequest(
                            new NetHttpTransport(),
                            JacksonFactory.getDefaultInstance(),
                            "https://www.googleapis.com/oauth2/v4/token",
//                        "https://accounts.google.com/o/oauth2/token",
                            clientSecrets.getDetails().getClientId(),
                            clientSecrets.getDetails().getClientSecret(),

                            authCode, //NOTE: was received from JavaScript client

                            "postmessage" //TODO: what's this? 
                            ).execute();
            String accessToken = tokenResponse.getAccessToken();
            String idToken = tokenResponse.getIdToken();

            //TODO: not getting a refresh token... why?!
            String refreshToken = tokenResponse.getRefreshToken();
            Boolean hasRefreshToken = new Boolean(!(refreshToken == null));
            LOGGER.warn("received refresh token: {}", hasRefreshToken);

            LOGGER.debug("accessToken: {}, refreshToken: {}, idToken: {}", accessToken, refreshToken, idToken);
            return accessToken;
        }catch (TokenResponseException tre){...}
Roy
  • 139
  • 3
  • 11
  • possible duplicate of https://stackoverflow.com/questions/10631042/how-to-generate-access-token-using-refresh-token-through-google-drive-api – ReyAnthonyRenacia Jun 05 '17 at 02:10
  • doesn't look like a duplicate. actually, looking for the first step completed in this post: "I have completed steps of authorization and obtained access token and refresh token.". That's what we need: to obtain the refresh token. someone else noted at the bottom of that post that he got it in PHP with $client->setAccessType("offline");). Question is how to get the initial refresh token using the Java API? – Roy Jun 05 '17 at 11:31

3 Answers3

3

Gmail API only gives the refresh token the first time you ask for the users permission. (At least this is what happens to me).

Go to: https://myaccount.google.com/permissions?pli=1, remove the authorization to your app and run your code. You should receive the refresh token.

  • Hi Ricardo, thanks but it doesn't seem to solve. Removing the app authorization will make the permissions prompt show again to the user but the result - not getting a refresh token - remains the same. – Roy Jun 06 '17 at 05:40
1

you should add the

  1. AccessType = "offline"

You need to call the function

new GoogleAuthorizationCodeRequestUrl(...).setAccessType("offline") 

or another syntax:

var authReq = new GoogleAuthorizationCodeRequestUrl(new Uri(GoogleAuthConsts.AuthorizationUrl)) { 
    RedirectUri = Callback, 
    ClientId = ClientId, 
    AccessType = "offline", 
    Scope = string.Join(" ", new[] { Scopes... }), 
    ApprovalPrompt = "force" 
};

in Fiddler you should see the following request:

https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/webmasters&redirect_uri=http://mywebsite.com/google/scapi/callback/&response_type=code&client_id=xxx&access_type=offline

see also here

More details about setAccessType can be found here

Tal Avissar
  • 10,088
  • 6
  • 45
  • 70
0

after finding how to use the Google APIs at the backend (documentation is somewhat partial..), the issue was fixed at the FrontEnd side by tweaking a parameter:

grantOfflineAccess({ - prompt: 'select_account' + prompt: 'consent'

HTH

Roy
  • 139
  • 3
  • 11