Google Drive API 在本地主机上工作,但在 Google App Engine 上出现 403 错误

问题描述 投票:0回答:1

我使用 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" }

初始化驱动服务的Java代码:
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();             
}

任何指导将不胜感激。谢谢!
记下我的尝试,

确保服务帐户具有适当的权限和访问范围。
  1. 仔细检查应用程序中以编程方式设置的访问范围。尝试直接添加链接
  2. .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"));
  3. 我尝试查看类似的问题,但找不到任何可以解决此问题的内容。
  4. 更新

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

默认情况下,客户端库将用户凭据存储在 
spring-boot google-cloud-platform google-app-engine google-drive-api
1个回答
0
投票

中的文件中 示例:

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);


© www.soinside.com 2019 - 2024. All rights reserved.