7

I would like to implement the auto-refresh method to obtain a new Access Token given the Refresh Token already taken from the first authorization flow.

Which method or list of methods should I call to do that? I'm using Java and OAuth 2.0 for Web Application. Given OAuth 2.0 WebApplication, what should I add in this code to get everything to work correctly?

Kirby
  • 15,127
  • 10
  • 89
  • 104
Aerox
  • 669
  • 1
  • 13
  • 28
  • I posted an answer here http://stackoverflow.com/a/42517728/266531 that I think addresses what you are after with more detail – Kirby Feb 28 '17 at 20:07

2 Answers2

8

The link you give in your question implements Google OAuth 2.0 authorization by using Google APIs Client Library for Java. And this library has implemented function of refresh access token .

So what you need is using Class GoogleRefreshTokenRequest in this library.

This class is Google-specific implementation of the OAuth 2.0 request to refresh an access token using a refresh token as specified in Refreshing an Access Token.

And its java doc also gives a sample usage:

static void refreshAccessToken() throws IOException {
try {
  TokenResponse response =
      new GoogleRefreshTokenRequest(new NetHttpTransport(), new JacksonFactory(),
          "tGzv3JOkF0XG5Qx2TlKWIA", "s6BhdRkqt3", "7Fjfp0ZBr1KtDRbnfVdmIw").execute();
  System.out.println("Access token: " + response.getAccessToken());
} catch (TokenResponseException e) {
  if (e.getDetails() != null) {
    System.err.println("Error: " + e.getDetails().getError());
    if (e.getDetails().getErrorDescription() != null) {
      System.err.println(e.getDetails().getErrorDescription());
    }
    if (e.getDetails().getErrorUri() != null) {
      System.err.println(e.getDetails().getErrorUri());
    }
  } else {
    System.err.println(e.getMessage());
  }
}

}

And This is another usage you can refer to.

You can add code below in CredentialManager.java, and when you need to refresh token, call this method.

public Credential refreshAccessToken(String refreshToken, String clientId, String clientSecret) throws IOException {
try {
  TokenResponse response =
  new GoogleRefreshTokenRequest(new NetHttpTransport(), new JacksonFactory(),
      refreshToken, clientId, clientSecret).execute();
  System.out.println("Access token: " + response.getAccessToken());
  return buildEmpty().setAccessToken(response.getAccessToken());
} catch (TokenResponseException e) {
  if (e.getDetails() != null) {
    System.err.println("Error: " + e.getDetails().getError());
    if (e.getDetails().getErrorDescription() != null) {
      System.err.println(e.getDetails().getErrorDescription());
    }
    if (e.getDetails().getErrorUri() != null) {
      System.err.println(e.getDetails().getErrorUri());
    }
  } else {
    System.err.println(e.getMessage());
  }
}

another method is use DataStoreCredentialRefreshListener

Access protected resources using the GoogleCredential. Expired access tokens will automatically be refreshed using the refresh token (if applicable). Make sure to use DataStoreCredentialRefreshListener and set it for the credential using GoogleCredential.Builder.addRefreshListener(CredentialRefreshListener).

Community
  • 1
  • 1
Owen Cao
  • 7,955
  • 2
  • 27
  • 35
  • Just calling the refreshAccessToken() method, Are my credentials automatically refreshed? Or after obtaining a TokenResponse i have to build and Empty Credential, adding/substituting the new Access Token and Re-load Credential from AppEngineCredentialStore? because i'm switched on an other example that is DrEdit (Java Version) using https://developers.google.com/drive/web/examples/java (https://github.com/googledrive/dredit/blob/master/java/src/com/google/drive/samples/dredit/CredentialManager.java) – Aerox Jun 10 '14 at 20:37
  • 1
    Yes, calling this method will not update your credential automatically, you need to reset your credential with new token. – Owen Cao Jun 11 '14 at 02:46
  • Thank you very much! you save me and many others. I think also that you can use even (as return): return buildEmpty().setFromTokenResponse(response); And it will work as well. Am i correct? :-) – Aerox Jun 11 '14 at 08:25
  • @OwenCao When i use the first function in my class , I am getting cannot fnd symbol error for TokenResponse and GoogleRefreshTokenRequest. Can you tell how to solve this. Whether i need to include jar files? – Santhosh Jun 18 '18 at 06:11
  • 1
    @Santhosh Yes, you need google-api-java-client, https://developers.google.com/api-client-library/java/ – Owen Cao Jun 18 '18 at 21:15
3
final GoogleCredential credential = new Builder()
        .setTransport(new NetHttpTransport())
        .setJsonFactory(new JacksonFactory())
        .setClientSecrets(OAuth2Provider.GOOGLE_CLIENT_ID, OAuth2Provider.GOOGLE_CLIENT_SECRET)
        .build()
        .setRefreshToken(refreshToken);

credential.refreshToken(); // do not forget to call

String newAccessToken = credential.getAccessToken();

Then you can use an object like UserTokens:

public class UserTokens {

    public final String accessToken;
    public final String refreshToken;

    public UserTokens(String accessToken, String refreshToken) {
        this.accessToken = accessToken;
        this.refreshToken = refreshToken;
    }

}

... and then store it in DB like:

TokenRepository tokenRepository = new PersistentTokenRepository();
tokenRepository.store(userTokens);

Notes

  • OAuth2Provider is my custom class where I keep client's id and secret
  • TokenRepository is a custom interface that has methods like store() and get()
  • PersistentTokenRepository is custom the implementation of the upper interface where you can store tokens in SQL or NoSQL databases like GAE
informatik01
  • 16,038
  • 10
  • 74
  • 104