Google API (버전 google-oauth-java-client-1.12.0-beta) OAuth2 액세스 토큰을 얻지 만 다시 "invalid_grant"를 받았습니다. 참고 : 여기에 https://developers.google.com/accounts/docs/OAuth2ServiceAccount서비스 계정 흐름에 대해 Google API [google-oauth-java-client-1.12.0-beta]를 사용하여 토큰을 가져올 수 없습니다.
코드입니다 :
import com.google.api.client.auth.jsontoken.JsonWebSignature;
import com.google.api.client.auth.jsontoken.JsonWebToken;
import com.google.api.client.auth.jsontoken.RsaSHA256Signer;
import com.google.api.client.auth.oauth2.TokenRequest;
import com.google.api.client.auth.oauth2.TokenResponse;
import com.google.api.client.http.GenericUrl;
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 com.google.api.client.util.Clock;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
public class TestClient
{
private static PrivateKey getPrivateKey(String keyFile, String alias, String password)
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException
{
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(new FileInputStream(keyFile), password.toCharArray());
PrivateKey privateKey = (PrivateKey) keystore.getKey(alias, password.toCharArray());
return privateKey;
}
public static void main(String[] args)
throws GeneralSecurityException, IOException
{
String password = "notasecret";
String alias = "privatekey";
String keyFile = "<private key file>.p12";
String serviceAccountScopes = "https://www.googleapis.com/auth/urlshortener";
String serviceAccountUser = "[email protected]";
String serviceAccountId = "<a/c id>.apps.googleusercontent.com";
JsonWebSignature.Header header = new JsonWebSignature.Header();
header.setAlgorithm("RS256");
header.setType("JWT");
JsonWebToken.Payload payload = new JsonWebToken.Payload(Clock.SYSTEM);
long currentTime = Clock.SYSTEM.currentTimeMillis();
payload.setIssuer(serviceAccountId)
.setAudience("https://accounts.google.com/o/oauth2/token")
.setIssuedAtTimeSeconds(currentTime/1000)
.setExpirationTimeSeconds(currentTime/1000 + 3600)
.setPrincipal(serviceAccountUser);
payload.put("scope", serviceAccountScopes);
System.out.println(payload.toPrettyString());
PrivateKey serviceAccountPrivateKey = getPrivateKey(keyFile, alias, password);
String assertion = RsaSHA256Signer.sign(serviceAccountPrivateKey, getJsonFactory(), header, payload);
TokenRequest request = new TokenRequest(getTransport(), getJsonFactory(), new GenericUrl(getTokenServerEncodedUrl()), "assertion");
request.put("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer");
request.put("assertion", assertion);
TokenResponse resp = request.execute();
System.out.println("token : " + resp.getAccessToken());
}
private static String getTokenServerEncodedUrl()
{
return "https://accounts.google.com/o/oauth2/token";
}
private static JsonFactory getJsonFactory()
{
return new JacksonFactory();
}
private static HttpTransport getTransport()
{
return new NetHttpTransport();
}
}
결과 :
Exception in thread "main" com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
"error" : "invalid_grant"
}
at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:103)
at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:303)
at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:323)
여기에 문제가 무엇입니까? 어떤 힌트라도 감사 할 것입니다.
애드 센스로 작업 할 때 여전히이 "invalid_grant"예외가 발생합니다. 클라이언트 ID가 유효하며 범위는 AdSenseScopes.ADSENSE입니다. 애드 센스 관리 API가 활성화되었습니다. 아무 단서도 그것을 고칠 수 없다 – user12384512
NodeJS 래퍼로 작업해도 큰 도움이된다. 내 문제는 응용 프로그램 전자 메일 주소 대신 내 계정 전자 메일을 사용했기 때문입니다. 감사! –
굉장한 답변! Google 스프레드 시트 자바 API로 JWT 오류가 발생했습니다. 서비스 계정을 통해 Google API 서비스에 자격 증명을 가져 오는 작업 Java 코드 예제를 찾는 것이 거의 불가능했습니다 (이 스레드 제외). 답변을 반영하기 위해 자격 증명을 바꿨을 때, 이제 Google 스프레드 시트 API를 통해 비공개 사용자에게 성공적으로 요청합니다. 또한 시트를 사용하여 작업 할 때 서비스 계정의 전자 메일 주소 (다운로드 한 json 키/ID 파일)의 개인 시트 (공유 단추를 통해)의 사용 권한을 허용하는지 확인하십시오 – ganta