我很难理解刷新和访问 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。
我的问题是
如果有人澄清我并把我赶出去,我会很满足的。我知道这个平台主要用于澄清代码方面的问题,但我的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/