Search code examples
javagoogle-apigoogle-analytics-apigoogle-api-java-clientgoogle-oauth

How does GoogleCredential token refresh work?


Here are my Credential and Analytics object customized via builders:

GoogleCredential credential = new GoogleCredential
        .Builder()
        .setClientSecrets("ClientSecretId", "Secret")
        .setTransport(HTTP_TRANSPORT)
        .setJsonFactory(JSON_FACTORY)
        .addRefreshListener(new CustomClientCredentialRefreshListener("SomeInfo", "AnotherInfo"))
        .build()

        .setAccessToken("accessToken")
        .setRefreshToken("refreshToken")

        .setExpiresInSeconds(3600L)
        .setExpirationTimeMilliseconds(1472659276L); //future date in epoch time

Analytics analytics = new Analytics.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
        .setApplicationName(APPLICATION_NAME)
        .setHttpRequestInitializer(credential)
        .build();

Why is the access token going to refresh when I call any api request? For example, when I get accounts:

Accounts accounts = analytics.management().accounts().list().execute();

I have the response. It's ok and nothing is wrong with it.

But the access token was not expired, yet. The long variable proves it here: setExpirationTimeMilliseconds()

However it is still refreshing and successfully returning a new access token to my refresh listener. Why?

What is setExpirationTimeMilliseconds() for?

Do I need to check expiration? Then do I set the refresh token in the credential only in the case that expired==true? Then, in other cases, I just set access token without refresh?


Solution

  • Solved! Problem was in Credendial method "getExpiresInSeconds()" that returns:

    (expirationTimeMilliseconds - clock.currentTimeMillis()) / 1000;
    

    My expirationTimeMilliseconds is 1472659276L

    currentTimeMillis returns for example: 1472734893827 (3 digits bigger than my nubmer)

      public void intercept(HttpRequest request) throws IOException {
    lock.lock();
    try {
      Long expiresIn = getExpiresInSeconds();
      // check if token will expire in a minute
      if (accessToken == null || expiresIn != null && expiresIn <= 60) {
        refreshToken();
        if (accessToken == null) {
          // nothing we can do without an access token
          return;
        }
      }
      method.intercept(request, accessToken);
    } finally {
      lock.unlock();
    }
    

    Token goes to refresh every time because

    if (accessToken == null || expiresIn != null && expiresIn <= 60)
    

    is true every time