使用OAuth 2.0 Google App Engine刷新访问令牌

时间:2014-06-09 20:14:58

标签: java google-app-engine oauth oauth-2.0 google-oauth

我想实现自动刷新方法,以获取已从第一个授权流程中获取的刷新令牌的新访问令牌。

我应该调用哪种方法或方法列表来执行此操作?我正在使用Java和OAuth 2.0进行Web应用程序。给定OAuth 2.0 WebApplication,我应该在此代码中添加什么才能使一切正常工作?

2 个答案:

答案 0 :(得分:5)

您在问题中提供的链接使用Google APIs Client Library for Java来实施Google OAuth 2.0授权。和 该库实现了刷新访问令牌的功能。

所以你需要的是在这个库中使用Class GoogleRefreshTokenRequest

  

此类是特定于Google的OAuth 2.0请求实现,使用Refreshing an Access Token中指定的刷新令牌刷新访问令牌。

它的java doc也提供了一个示例用法:

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

}

这是你可以参考的another usage

您可以在CredentialManager.java中添加以下代码,当您需要刷新令牌时,请调用此方法。

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

另一种方法是使用DataStoreCredentialRefreshListener

  

使用GoogleCredential访问受保护的资源。过期的访问令牌将使用刷新令牌自动刷新(如果适用)。请务必使用DataStoreCredentialRefreshListener并使用GoogleCredential.Builder.addRefreshListener(CredentialRefreshListener)将其设置为凭据。

答案 1 :(得分:1)

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

然后你可以使用像UserTokens这样的对象:

public class UserTokens {
  public final String accessToken;
  public final String refreshToken;

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

...然后在DB中疼痛,如:

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

PS:

OAuth2Provider是我的自定义类,我保留了客户端的ID和秘密。

TokenRepository是自定义接口,具有store()和get()

等方法

PersistentTokenRepository是自定义上层接口的实现,您可以在其中存储SQL或NoSQL DB(如GAE)中的令牌。