Google Gmail API 使用 Java SDK 请求服务凭证返回 400
Google Gmail API request with service credential returning 400 using Java SDK
我正在尝试使用带有服务帐户凭据的 Gmail API 和 Java SDK (v1.22.0) 访问我自己的个人 Gmail 帐户。我已经生成了凭据并在本地保存了 json 文件,然后尝试了 运行 这个:
public class GmailAPI测试{
public static void main(String[] args) throws Exception {
JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
HttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
String filepath = "/path/to/my/creds.json";
GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream(filepath))
.createScoped(Collections.singleton(GmailScopes.GMAIL_READONLY));
Gmail service = new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName("MyApp")
.build();
String user = "me";
ListLabelsResponse listResponse = service.users().labels().list(user).execute();
List<Label> labels = listResponse.getLabels();
if (labels.size() == 0) {
System.out.println("No labels found.");
} else {
System.out.println("Labels:");
for (Label label : labels) {
System.out.printf("- %s\n", label.getName());
}
}
}
我收到这样的 400 响应:
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Bad Request",
"reason" : "failedPrecondition"
} ],
"message" : "Bad Request"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:146)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.interceptResponse(AbstractGoogleClientRequest.java:321)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1065)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at ie.test.GmailAPITest.main(GmailAPITest.java:34)
我试过在服务凭证上启用全域委派,我试过将用户 "me" 更改为我帐户的电子邮件地址,但结果相同。我也看过一些有类似问题的问题,但我没有发现任何有用的问题。我错过了什么吗?
Gmail API 已从开发人员控制台启用,从那里我可以看到所有失败的 4xx 请求。
我还应该提到我已经使用 Python 创建了另一个测试,它使用相同的服务凭证做完全相同的事情,但失败并出现相同的 400 错误。我已经尝试在相同的安全凭证下创建一个新密钥 (json) 并尝试使用它,但结果相同。
我已经能够让事情正常进行,但只能通过使用替代的 oAuth 登录过程,即被提示从网络浏览器 allow/deny 访问,然后节省一些o授权未来用户访问文件的令牌。这并不理想,因为我将不得不不断地更新这些令牌。据推测,创建服务凭证是为了避免那个确切的问题。我仍然很想知道为什么它对我不起作用。
服务帐户域范围的授权仅适用于 G Suite 帐户,需要 G Suite 管理员授权服务帐户客户端 ID 才能访问必要的范围。如果您使用的是消费者 Gmail 帐户(@gmail.com 地址)或者您没有 G Suite 管理员批准,那么您应该像现在一样使用正常的 OAuth 流程。
我正在尝试使用带有服务帐户凭据的 Gmail API 和 Java SDK (v1.22.0) 访问我自己的个人 Gmail 帐户。我已经生成了凭据并在本地保存了 json 文件,然后尝试了 运行 这个:
public class GmailAPI测试{
public static void main(String[] args) throws Exception {
JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
HttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
String filepath = "/path/to/my/creds.json";
GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream(filepath))
.createScoped(Collections.singleton(GmailScopes.GMAIL_READONLY));
Gmail service = new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName("MyApp")
.build();
String user = "me";
ListLabelsResponse listResponse = service.users().labels().list(user).execute();
List<Label> labels = listResponse.getLabels();
if (labels.size() == 0) {
System.out.println("No labels found.");
} else {
System.out.println("Labels:");
for (Label label : labels) {
System.out.printf("- %s\n", label.getName());
}
}
}
我收到这样的 400 响应:
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Bad Request",
"reason" : "failedPrecondition"
} ],
"message" : "Bad Request"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:146)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.interceptResponse(AbstractGoogleClientRequest.java:321)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1065)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at ie.test.GmailAPITest.main(GmailAPITest.java:34)
我试过在服务凭证上启用全域委派,我试过将用户 "me" 更改为我帐户的电子邮件地址,但结果相同。我也看过一些有类似问题的问题,但我没有发现任何有用的问题。我错过了什么吗?
Gmail API 已从开发人员控制台启用,从那里我可以看到所有失败的 4xx 请求。
我还应该提到我已经使用 Python 创建了另一个测试,它使用相同的服务凭证做完全相同的事情,但失败并出现相同的 400 错误。我已经尝试在相同的安全凭证下创建一个新密钥 (json) 并尝试使用它,但结果相同。
我已经能够让事情正常进行,但只能通过使用替代的 oAuth 登录过程,即被提示从网络浏览器 allow/deny 访问,然后节省一些o授权未来用户访问文件的令牌。这并不理想,因为我将不得不不断地更新这些令牌。据推测,创建服务凭证是为了避免那个确切的问题。我仍然很想知道为什么它对我不起作用。
服务帐户域范围的授权仅适用于 G Suite 帐户,需要 G Suite 管理员授权服务帐户客户端 ID 才能访问必要的范围。如果您使用的是消费者 Gmail 帐户(@gmail.com 地址)或者您没有 G Suite 管理员批准,那么您应该像现在一样使用正常的 OAuth 流程。