我很难理解刷新和访问 token 的正确用法。我知道刷新 token 与授权有关,访问 token 与身份验证有关。我想更好地解释我的用例,以便有人可以在这里帮助我。我在Google Merchant Center中有一个多帐户中心。我想在代码中集成最新的OAuth 2.0身份验证机制。我确实可以成功进行身份验证。我使用构建凭据对象的Google凭据机制,并在对Google进行httprequest期间使用httprequestinitializer机制进行注入(inject)。当创建google凭据对象时,我看到当我执行googleCredential.getAccessToken()时没有访问 token ,但是当我执行googleCredential.refreshToken()然后执行googleCredential.getAccessToken()时,我获得了accessToken 。但是,我正在测试 token 的创建方式,没有在请求中明确将这些 token 传递给google。我所传递的只是带有客户 secret 和其他私钥的googleCredential对象。我正在做的任务只是通过cron脚本将子帐户产品供稿上传到google。

我的问题是

  • 在这里传递googleCredential对象时,我是否必须照顾这里的刷新 token ? (假设脚本运行了一天以上)
  • 什么时候应该使用刷新 token 和访问 token ,在上述用例中,什么是对我合适的选择? (尽管到目前为止,除了googleCredential对象之外,我没有明确传递任何东西)
  • 访问 token 和刷新 token 的有效时间是多少(与上述用例无关,只是知道,有人说刷新 token 需要14天,有人说不确定直到用户撤销访问权限,等等)

    如果有人澄清我并把我赶出去,我会很满足的。我知道这个平台主要用于澄清代码方面的问题,但我的Google论坛也无济于事。所以在这里发布。

    很抱歉,很冗长。

    提前致谢。

    最佳答案

    所谓的 OfflineCredentials 需要刷新 token 。这些凭证可由未在浏览器中运行的应用程序使用(例如,桌面应用程序或某些没有UI的批处理),因此无法执行OAuth2流。
    请看看Using OAuth 2.0 to Access Google APIs

    有关Offline Access的更多信息!
    在Java中,它将如下所示:

    import com.google.api.ads.common.lib.auth.OfflineCredentials;
    import com.google.api.ads.common.lib.auth.OfflineCredentials.Api;
    import com.google.api.ads.common.lib.auth.OfflineCredentials.ForApiBuilder;
    import com.google.api.ads.common.lib.exception.OAuthException;
    import com.google.api.ads.common.lib.exception.ValidationException;
    import com.google.api.client.auth.oauth2.Credential;
    
    // ...
    
    // Generate offline credentials
    // With a previously created OAuth2 refresh token (see API examples)
    ForApiBuilder forApiBuilder = new OfflineCredentials.Builder().forApi(Api.ADWORDS);
    forApiBuilder.withClientSecrets(clientId, clientSecret);
    forApiBuilder.withRefreshToken(refreshToken);
    
    Credential credential = null;
    try {
      credential = forApiBuilder.build().generateCredential();
    } catch (OAuthException e) {
      throw new Exception("The given credential could not be refreshed: " + e.getMessage());
    } catch (ValidationException e) {
      throw new Exception("Client ID, client secret or refresh token are not valid: " + e.getMessage());
    }
    
    // Build session
    // ...
    
    除了客户机ID和客户机 secret 之外,还需要将刷新 token 传递给凭证生成器。使用有效的OfflineCredentials,您现在可以为特定的Google API建立新的 session 。
    关于您的第三个问题:请参阅以下question的已接受答案
    此处的源代码显示了如何通过命令行一次获取 Google AdWords(请参见范围)的刷新 token 。客户端ID和客户端 secret 必须作为命令行参数传递。
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    
    import org.apache.commons.configuration.Configuration;
    import org.apache.commons.configuration.PropertiesConfiguration;
    
    import com.google.api.ads.common.lib.auth.GoogleClientSecretsBuilder;
    import com.google.api.ads.common.lib.auth.GoogleClientSecretsBuilder.Api;
    import com.google.api.ads.common.lib.auth.GoogleClientSecretsBuilder.GoogleClientSecretsForApiBuilder;
    import com.google.api.ads.common.lib.exception.ValidationException;
    import com.google.api.client.auth.oauth2.Credential;
    import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
    import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest;
    import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
    import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
    import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
    import com.google.api.client.http.javanet.NetHttpTransport;
    import com.google.api.client.json.jackson2.JacksonFactory;
    import com.google.common.collect.Lists;
    
    // ...
    
      private static final String SCOPE = "https://adwords.google.com/api/adwords";
    
      // This callback URL will allow you to copy the token from the success screen
      private static final String CALLBACK_URL = "urn:ietf:wg:oauth:2.0:oob";
    
      public static void main(String[] args) throws Exception {
        if (args.length != 2) {
          System.err.println("Please provide client ID and secret as commandline arguments!");
          System.err.println("If you do not have a client ID or secret, please create one in the API console: https://code.google.com/apis/console#access");
          System.exit(1);
        }
    
        GoogleClientSecrets clientSecrets = null;
        try {
          Configuration configuration = new PropertiesConfiguration();
          configuration.setProperty("api.adwords.clientId", args[0]);
          configuration.setProperty("api.adwords.clientSecret", args[1]);
    
          GoogleClientSecretsForApiBuilder googleClientSecretsForApiBuilder = new GoogleClientSecretsBuilder().forApi(Api.ADWORDS);
          googleClientSecretsForApiBuilder.from(configuration);
    
          clientSecrets = googleClientSecretsForApiBuilder.build();
        } catch (ValidationException e) {
          System.err.println("Invalid client ID or secret!");
          System.exit(1);
        }
    
        // Get the OAuth2 credential
        Credential credential = getOAuth2Credential(clientSecrets);
    
        System.out.printf("Your refresh token is: %s\n", credential.getRefreshToken());
        }
      }
    
      private static Credential getOAuth2Credential(GoogleClientSecrets clientSecrets) throws Exception {
        /*
         * Set the access type to offline so that the token can be refreshed. By
         * default, the library will automatically refresh tokens when it can, but
         * this can be turned off by setting api.adwords.refreshOAuth2Token=false
         */
        GoogleAuthorizationCodeFlow authorizationFlow = new GoogleAuthorizationCodeFlow.Builder(new NetHttpTransport(), new JacksonFactory(), clientSecrets, Lists.newArrayList(SCOPE)).setAccessType("offline").build();
    
        String authorizeUrl = authorizationFlow.newAuthorizationUrl().setRedirectUri(CALLBACK_URL).build();
        System.out.println("Paste this url in your browser: \n" + authorizeUrl + '\n');
    
        // Wait for the authorization code
        System.out.println("Type the code you received here: ");
        String authorizationCode = new BufferedReader(new InputStreamReader(System.in)).readLine();
    
        // Authorize the OAuth2 token
        GoogleAuthorizationCodeTokenRequest tokenRequest = authorizationFlow.newTokenRequest(authorizationCode);
        tokenRequest.setRedirectUri(CALLBACK_URL);
        GoogleTokenResponse tokenResponse = tokenRequest.execute();
    
        // Create the OAuth2 credential
        GoogleCredential credential = new GoogleCredential.Builder().setTransport(new NetHttpTransport()).setJsonFactory(new JacksonFactory()).setClientSecrets(clientSecrets).build();
    
        // Set authorized credentials
        credential.setFromTokenResponse(tokenResponse);
    
        return credential;
      }
    
    该代码最初来自Goolge AdWords API example。我的版本不是从配置文件中读取的,因为我不想将客户端ID和密码存储在某些资源文件中(以后我忘记将其删除)。这就是为什么将值作为参数传递给程序的原因。

    关于google-oauth - OAuth 2.0访问 token 和刷新 token ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28272849/

  • 10-16 15:09