OAuth 2.0访问令牌和刷新令牌 [英] OAuth 2.0 Access Tokens and Refresh Tokens

查看:154
本文介绍了OAuth 2.0访问令牌和刷新令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have difficult in understanding the proper usage of refresh and access tokens. I know that refresh tokens are related to authorization and access tokens are related to authentication.I would like to explain my use case better so that someone could help me out here. I have a Multi Account Center in Google Merchant Center. I would like to integrate the latest OAuth 2.0 authentication mechanism in my code. I did and could authenticate successfully. I use Google Credential mechanism of building a credential object and inject in using the httprequestinitializer mechanism during httprequest to google. When the google credential object is created , I see that there is no access tokens when I do a googleCredential.getAccessToken(), but then when I do a googleCredential.refreshToken() and then a googleCredential.getAccessToken() , I get an accessToken. However, I was testing how the tokens are created and I am not explicitly passing these tokens in the request to google. All I pass is just the googleCredential object with client secrets and other private keys. The task I am doing is just uploading the sub account product feeds to google via cron script.

我的问题是


  1. 在这里传递googleCredential对象时,我是否必须照顾这里的刷新令牌? (假设脚本运行了一天以上)

  2. 何时应该使用刷新令牌和访问令牌,在上述用例中,对我来说合适的选择是什么? (尽管目前我没有传递googleCredential对象以外的任何东西)

  3. 访问令牌和刷新令牌的有效时间是多长时间(与上述用例无关,只是要知道,有人说14天的刷新令牌,有人说是无限期的,直到用户撤消访问权限,等等)

如果有人澄清我的话,我会很高兴的把我拉出来我知道这个平台主要用于澄清代码方面的问题,但我的Google论坛也无济于事。因此,发布在这里。

I would be great full if someone clarifies me and pulls me out. I know this platform is to clarify issues majorly on code but I google forum isn't helping either. So posting here.

很抱歉,太冗长了。

请先谢谢。

推荐答案

所谓的 OfflineCredentials 需要一个刷新令牌。这些是凭据,可由未在浏览器中运行的应用程序使用(例如,桌面应用程序或某些没有UI的批处理),因此无法执行OAuth2流。

A refresh token is required for so called OfflineCredentials. These are credentials, that can be used by applications, which are not running in a browser (e.g. desktop applications or some batch processing without UI) and therefore cannot perform an OAuth2 flow.

请查看使用OAuth 2.0访问Google API



  1. 如有必要,刷新访问令牌。

访问令牌的寿命有限。如果您的应用程序需要在单个访问令牌的生存期之外访问Google API,则可以获取刷新令牌。刷新令牌允许您的应用程序获取新的访问令牌。

Access tokens have limited lifetimes. If your application needs access to a Google API beyond the lifetime of a single access token, it can obtain a refresh token. A refresh token allows your application to obtain new access tokens.

注意:将刷新令牌保存在安全的长期存储中,并在它们保持有效的情况下继续使用它们。限制适用于每个客户端-用户组合以及所有客户端上的每个用户发出的刷新令牌的数量,这些限制是不同的。如果您的应用程序请求足够的刷新令牌以超过限制之一,则较旧的刷新令牌将停止工作。

Note: Save refresh tokens in secure long-term storage and continue to use them as long as they remain valid. Limits apply to the number of refresh tokens that are issued per client-user combination, and per user across all clients, and these limits are different. If your application requests enough refresh tokens to go over one of the limits, older refresh tokens stop working.

提供更多信息href = https://developers.google.com/accounts/docs/OAuth2WebServer#offline rel = nofollow noreferrer>离线访问

在Java中,它将如下所示:

In Java, it will look like this:

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和客户机密钥外,还需要将刷新令牌传递给凭证生成器。有了有效的OfflineCredentials,您现在就可以为特定的Google API建立新会话。

The refresh token need to be passed to the credential builder in addition to the client ID and the client secret. With the valid OfflineCredentials you are now able to build a new session for a specific Google API.

关于第三个问题:请参见已接受的答案以下问题

Regarding your third question: See the accepted answer of following question

此处的源代码显示了如何通过命令行一次获取 Google AdWords(请参阅范围)的刷新令牌。客户端ID和客户端密钥必须作为命令行参数传递。

Here the source code, which shows how to obtain a refresh token for Google AdWords (see scope) once via commandline. The client ID and the client secret must be passed as commandline arguments.

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示例 。我的版本不是从配置文件中读取的,因为我不想将客户端ID和密码存储在某些资源文件中(以后我忘记将其删除)。这就是为什么将值作为参数传递给程序的原因。

The code is originally from a Goolge AdWords API example. My version is not reading from a configuration file, because I didn't want to store the client ID and secret in some resource file (which I forgot to remove later on). That's why the values are passed as arguments to the program.

这篇关于OAuth 2.0访问令牌和刷新令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆