我使用 Java Spring Boot 开发了一个全栈应用程序,它使用 Google Drive API v3 来处理文件。该应用程序托管在 Google Cloud Platform (GCP) 环境中的 Google App Engine 上。
问题:
在本地 (localhost) 运行应用程序时,Google Drive API 可以正常运行。但是,当应用程序部署并在 Google App Engine 上运行时,当尝试执行与 Drive API 相关的任何操作(例如创建文件等)时,会遇到 403 错误并显示以下消息:“ACCESS_TOKEN_SCOPE_INSUFFICIENT”。
关键细节:
该应用程序正在使用服务帐户通过 Google Drive API 进行身份验证。我还以编程方式设置了必要的访问范围。尽管配置正确,但仅当应用程序托管在 Google App Engine 上时,问题仍然存在。应用程序引擎日志:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
POST https://www.googleapis.com/upload/drive/v3/files?fields=id&uploadType=resumable
{
"code": 403,
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT",
"domain": "googleapis.com",
"metadata": {
"method": "google.apps.drive.v3.DriveFiles.Create",
"service": "drive.googleapis.com"
}
}
],
"errors": [
{
"domain": "global",
"message": "Insufficient Permission",
"reason": "insufficientPermissions"
}
],
"message": "Request had insufficient authentication scopes.",
"status": "PERMISSION_DENIED"
}
public static Drive initDriveService() throws IOException {
GoogleCredentials credentials = GoogleCredentials
.getApplicationDefault() //set to the service account
.createScoped(Collections.singleton(DriveScopes.DRIVE_FILE));
HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials);
return new Drive.Builder(new NetHttpTransport(),GsonFactory.getDefaultInstance(),requestInitializer).setApplicationName("Demo Application").build();
}
任何指导将不胜感激。谢谢!记下我的尝试,
确保服务帐户具有适当的权限和访问范围。
.createScoped(Arrays.asList("openid","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/ drive.file"));
我尝试查看类似的问题,但找不到任何可以解决此问题的内容。
App Engine 版本的启动日志:
c.g.c.s.core.DefaultCredentialsProvider : Default credentials provider for Google Compute Engine."
来自本地托管版本的启动日志:
c.g.c.s.core.DefaultCredentialsProvider : Default credentials provider for service account xxxxxxxxxx.iam.gserviceaccount.com
默认情况下,客户端库将用户凭据存储在
中的文件中 示例:
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, JSON_FACTORY, clientSecrets,
Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(dataStoreFactory)
.build();
即使您没有添加
.setDataStoreFactory(dataStoreFactory)
,它仍然会自动设置。然后,用户凭据访问令牌和刷新令牌将存储在计算机上某个位置的文件中。当您更改代码中的范围时,它不会请求您再次授权,因为它认为它仍然具有有效的刷新令牌,并且正在将其与旧范围一起使用。
现在坦白说,我不是 Java 开发人员,但这个库非常接近 .Net 库。您需要做的是将
setDataStoreFactory
添加到您的代码中,然后它将将该文件存储在您选择的目录中。然后它应该再次请求用户的授权。这次范围正确。
这样的事情应该为您创建一个新的 FileDataStoreFactory 工厂
private static FileDataStoreFactory dataStoreFactory;
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);