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

Posted

技术标签:

【中文标题】使用 OAuth 2.0 Google App Engine 刷新访问令牌【英文标题】:Refresh Access Token with OAuth 2.0 Google App Engine 【发布时间】:2014-07-30 11:06:41 【问题描述】:

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

我应该调用哪个方法或方法列表来做到这一点?我正在为 Web 应用程序使用 Java 和 OAuth 2.0。鉴于OAuth 2.0 WebApplication,我应该在这段代码中添加什么才能让一切正常工作?

【问题讨论】:

我在这里***.com/a/42517728/266531 发布了一个答案,我认为它可以更详细地解决您所追求的问题 【参考方案1】:

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

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

此类是 OAuth 2.0 请求的 Google 特定实现,用于使用 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中添加如下代码,当需要刷新token时,调用该方法。

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) 将其设置为凭据。

【讨论】:

只是调用 refreshAccessToken() 方法,我的凭据会自动刷新吗?或者在获得 TokenResponse 后,我必须构建并清空凭据,添加/替换新的访问令牌并从 AppEngineCredentialStore 重新加载凭据?因为我使用developers.google.com/drive/web/examples/java (github.com/googledrive/dredit/blob/master/java/src/com/google/…) 开启了另一个示例,即 DrEdit(Java 版本) 是的,调用此方法不会自动更新您的凭证,您需要使用新令牌重置您的凭证。 非常感谢!你救了我和其他许多人。我认为您甚至可以使用(作为返回): return buildEmpty().setFromTokenResponse(response);它也将起作用。我对么? :-) @OwenCao 当我在课堂上使用第一个函数时,我得到了无法找到 TokenResponse 和 GoogleRefreshTokenRequest 的符号错误。你能告诉如何解决这个问题。我是否需要包含 jar 文件? @Santhosh 是的,你需要 google-api-java-client,developers.google.com/api-client-library/java【参考方案2】:
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;
    


...然后将其存储在数据库中:

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

注意事项

OAuth2Provider 是我的自定义类,我在其中保留客户的 id秘密 TokenRepository 是一个自定义接口,具有 store()get() PersistentTokenRepository是自定义上层的实现 您可以将令牌存储在 SQL 或 NoSQL 数据库中的接口,例如 GAE

【讨论】:

以上是关于使用 OAuth 2.0 Google App Engine 刷新访问令牌的主要内容,如果未能解决你的问题,请参考以下文章

OAuth 2.0 Cookbook: Protect your web APP using SpringSecurity

服务帐户的 google OAuth 2.0 是 OAuth 2.0 标准的一部分吗?

OAuth 2.0 适用于 Google 表格,但不适用于 Google Calendar API

javascript 这是一套Google Apps脚本(或Adwords Scripty)Oauth 2.0功能集。我们的想法是您可以使用它来启动OAuth 2.0流程

适用于 Google Bigquery 的 Oauth 2.0

将 OAuth 2.0 和 Google 电子表格 API 与 Java 结合使用的示例是啥?