服务账户类的OAuth2.0认证,谷歌官方提供了google-api-client
maven 包。分享一个我在对接该认证过程中的一个坑。
要对接Google API 需要引入google-api-client
库
<!-- https://mvnrepository.com/artifact/com.google.api-client/google-api-client -->
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.23.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.apis/google-api-services-oauth2 -->
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-oauth2</artifactId>
<version>v2-rev139-1.23.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.oauth-client/google-oauth-client-jetty -->
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-jetty</artifactId>
<version>1.23.0</version>
</dependency>
示例代码可以参见极客学院整理的 Google OAuth 2.0 认证指南
以我的代码为例(调用谷歌的 travelpartner api)
package com.hpa;
import com.google.api.client.googleapis.GoogleUtils;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.security.GeneralSecurityException;
import java.util.Collections;
public class GoogleOauth {
private static final String P12 = "d0d079418de6.p12"; //私钥文件
private static final String PROXY_HOST = "代理host";
private static final Integer PROXY_PORT = 8080; //代理端口
private static final String ACCOUNT_EMAIL = "service account email address";
private static final String TRAVEL_PARTNER_SCOPE = "https://www.googleapis.com/auth/travelpartner"; //即你要申请的可以访问哪些api的范围
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static HttpTransport getHttpTransport() throws IOException, GeneralSecurityException {
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT));
return new NetHttpTransport.Builder()
.trustCertificates(GoogleUtils.getCertificateTrustStore())
.setProxy(proxy) //如果被墙需要设置代理
.build();
}
private static String getAccessToken() throws GeneralSecurityException, IOException {
HttpTransport httpTransport = getHttpTransport();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(ACCOUNT_EMAIL)
.setServiceAccountPrivateKeyFromP12File(new File(P12))
.setServiceAccountScopes(Collections.singleton(TRAVEL_PARTNER_SCOPE))
.build();
return credential.getAccessToken();
}
public static void main(String[] args) throws GeneralSecurityException, IOException {
System.out.println(getAccessToken());
}
}
运行结果始终为null
,我查阅大量资料,直到看到了这篇帖子# 如何从GoogleCredential获得访问令牌?
原来只需要在credential.getAccessToken()
之前先执行credential.refreshToken();
即可
坑爹的是,包括官网在内好多资料都没有表明要先执行刷新token
操作!!!
//修改后
credential.refreshToken();// 一定要调用,否则为null
return credential.getAccessToken();