开发google api 的时候遇到的问题 需要维护google上的搜索商品 google 需要获取access token 才能正常调用
相关文档
google api 文档
请求示例和文档
https://developers.google.com/shopping-content/v2/quickstart
身份平台
https://developers.google.com/identity/protocols/OAuth2ServiceAccount
创建项目生成json和p12文件
https://console.cloud.google.com/projectselector2/iam-admin/serviceaccounts?supportedpurview=project
创建项目
https://console.developers.google.com/cloud-resource-manager
https://developers.google.com/identity/protocols/OpenIDConnect
google身份平台
https://developers.google.com/identity/protocols/OAuth2ServiceAccount
作用域
https://developers.google.com/identity/protocols/googlescopes
api请求 示例
https://developers.google.com/identity/protocols/OAuth2ServiceAccount
网上看了很多相关文章 没有直接获取access token的 大部分都是需要 url 重定向 取URL里面的code 然后用code取access token
服务端这样处理比较难 应该是直接调一个接口返回 access token 这样处理比较方便
前面的步骤简单说一下
1.创建服务项目
2.生成加密文件 (json或者p12)
这两个步骤网上都有教程
获取access token
方式一 直接用google原生的api
public static void main(String[] args) throws IOException {
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
GoogleCredentials credential = GoogleCredentials.fromStream(Demo1.class.getResourceAsStream("加密的json文件路径"))
.createScoped(Arrays.asList("https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/content"));//设置作用域
credential.refresh();
String accessToken = credential.getAccessToken().getTokenValue();
System.out.println(accessToken);
ComputeCredential computeCredential = new ComputeCredential(httpTransport,jsonFactory);
computeCredential.setAccessToken(accessToken);
ShoppingContent service = new ShoppingContent
.Builder(httpTransport, jsonFactory, computeCredential)
.build();
ShoppingContent.Products.List productList = service.products().list(BigInteger.valueOf(110141822));
ProductsListResponse page = productList.execute();
List<Product> resources = page.getResources();
System.out.println(page.toString());
//插入和更新
// service.products().insert(BigInteger.valueOf(110141822),new Product());
//
// //批量插入和更新
// ProductsCustomBatchRequest productsCustomBatchRequest = new ProductsCustomBatchRequest();
// List<ProductsCustomBatchRequestEntry> updates = new ArrayList();
// ProductsCustomBatchRequestEntry info = new ProductsCustomBatchRequestEntry();
// info.setProduct(new Product());
// productsCustomBatchRequest.setEntries(updates);
// service.products().custombatch(productsCustomBatchRequest);
}
方式二 生成jwt字符串 再掉接口取access token
a.使用 jjwt 方式生成JWT
private static String getJwt() throws InvalidKeyException {
String private_key = getPrivateKey(); //json文件中的private_key 记得删除 头和尾的不必要字符串
long now = System.currentTimeMillis() / 1000;
Map<String, Object> heads = new HashMap();
heads.put("typ", "JWT");
heads.put("alg", "RS256");
System.out.println(JSON.toJSONString(heads));
Claims claims = Jwts.claims();
claims.put("iss", "content-api@iconic-vine-270102.iam.gserviceaccount.com");
claims.put("scope", "https://www.googleapis.com/auth/content");
claims.put("aud", "https://oauth2.googleapis.com/token");
claims.put("exp", now + 3600 + "");
claims.put("iat", now + "");
System.out.println(JSON.toJSONString(claims));
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.RS256;
byte[] apikeys = DatatypeConverter.parseBase64Binary(private_key);
Key key = RSAPrivateCrtKeyImpl.newKey(apikeys);
String str = Jwts.builder()
.setHeader(heads)
.setClaims(claims)
.setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000)) //token保留的时间
.signWith(signatureAlgorithm, key) //
.compact();
System.out.println(str);
return str;
}
public static String getPrivateKey(){ String jsonStr = ""; try { File jsonFile = new File("加密json问价路径"); FileReader fileReader = new FileReader(jsonFile); Reader reader = new InputStreamReader(new FileInputStream(jsonFile),"utf-8"); int ch = 0; StringBuffer sb = new StringBuffer(); while ((ch = reader.read()) != -1) { sb.append((char) ch); } fileReader.close(); reader.close(); jsonStr = sb.toString(); return JSON.parseObject(jsonStr).get("private_key").toString().replace("-----BEGIN PRIVATE KEY-----\n", "").replace("\n-----END PRIVATE KEY-----\n", ""); } catch (IOException e) { e.printStackTrace(); return null; } } b.谷歌原生api生成jwt
private static String getJwt() throws GeneralSecurityException, IOException {
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
GoogleCredential credential = GoogleCredential.fromStream(Demo3.class.getResourceAsStream("加密json文件路径"));
credential.createScoped(Collections.singleton(ShoppingContentScopes.CONTENT));
PrivateKey privateKey = credential.getServiceAccountPrivateKey();
long now = System.currentTimeMillis() / 1000;
JsonWebSignature.Header header = new JsonWebSignature.Header();
header.put("typ", "JWT");
header.put("alg", "RS256");
System.out.println(JSON.toJSONString(header));
JsonWebToken.Payload payload = new JsonWebSignature.Payload();
payload.put("iss", "content-api@iconic-vine-270102.iam.gserviceaccount.com");
payload.put("scope", "https://www.googleapis.com/auth/content");
payload.put("aud", "https://oauth2.googleapis.com/token");
payload.put("exp", now + 3600);
payload.put("iat", now);
System.out.println(JSON.toJSONString(payload));
String s = JsonWebSignature.signUsingRsaSha256(privateKey, jsonFactory, header, payload);
System.out.println(s);
return s;
}
google 根据jwt 生成 access token 的接口
https://oauth2.googleapis.com/token
post请求 form表单形式提交参数
grant_type urn:ietf:params:oauth:grant-type:jwt-bearer (固定写法)
assertion jwt字符串
pom相关
<dependencies>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-oauth2</artifactId>
<version>v2-rev20200213-1.30.9</version>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-content</artifactId>
<version>v2.1-rev20200219-1.30.9</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.0</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-jackson2</artifactId>
<version>1.34.2</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-jetty</artifactId>
<version>1.30.6</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-servlet</artifactId>
<version>1.30.6</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
</dependency>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.30.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-oauth2-http</artifactId>
<version>0.20.0</version>
</dependency>
</dependencies>
千万注意账户对应权限 如果对应不上会导致很奇怪的问题