我很难理解刷新和访问令牌的正确用法。我知道刷新令牌与授权有关,访问令牌与身份验证有关。我想更好地解释我的用例,以便有人可以帮助我。我在Google Merchant Center中设有多帐户中心。我想在我的代码中集成最新的OAuth 2.0身份验证机制。我做了,可以成功验证。我使用Google Credential机制构建凭证对象,并在httprequest期间使用httprequestinitializer机制注入谷歌。创建google凭据对象时,我发现当我执行googleCredential.getAccessToken()时没有访问令牌,但是当我执行googleCredential.refreshToken()然后googleCredential.getAccessToken()时,我获得了accessToken 。但是,我正在测试令牌是如何创建的,而且我没有明确地在google请求中传递这些令牌。我传递的只是带有客户端机密和其他私钥的googleCredential对象。我正在做的任务就是通过cron脚本将子帐户产品Feed上传到谷歌。
我的问题是,
抱歉非常详细。
提前致谢。
答案 0 :(得分:7)
所谓的 OfflineCredentials 需要刷新令牌。这些是可由应用程序使用的凭据,这些凭据不在浏览器中运行(例如,桌面应用程序或某些没有UI的批处理),因此无法执行OAuth2流程。
请查看Using OAuth 2.0 to Access Google APIs
- 如有必要,请刷新访问令牌。
醇>访问令牌的生命周期有限。如果您的应用需要在单个访问令牌的生命周期之后访问Google API,则可以获取刷新令牌。刷新令牌允许您的应用程序获取新的访问令牌。
注意:在安全的长期存储中保存刷新令牌,只要它们仍然有效,就继续使用它们。限制适用于每个客户端 - 用户组合以及所有客户端中的每个用户发布的刷新令牌的数量,并且这些限制是不同的。如果您的应用程序请求足够的刷新令牌超过其中一个限制,则较旧的刷新令牌将停止工作。
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和客户端密钥之外,还需要将刷新令牌传递给凭据构建器。借助有效的OfflineCredentials,您现在可以为特定的Google API构建新会话。
关于您的第三个问题:请参阅以下question
的接受回答此处是源代码,其中显示了如何通过命令行获取 Google AdWords(请参阅范围)的刷新令牌。必须将客户端ID和客户端密钥作为命令行参数传递。
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和密码存储在某个资源文件中(我以后忘记删除)。这就是为什么值作为参数传递给程序。