2

我正在编写一个 App Engine Web 应用程序,它从 Google Drive 上的文件夹中加载图片库。该代码在本地运行时运行良好(图像被检索并正确显示在网页上),但在 Google App Engine 上部署时它会中断。具体来说,启动如下方法时,返回的Drive服务为null,不抛出异常。凭据(SERVICE_ACCOUNT_EMAIL 和 PKCS12 文件)应该是正确的,因为它们在本地运行代码时有效。我在这里想念什么?提前致谢。

public static Drive getDriveService() {
    HttpTransport httpTransport = new NetHttpTransport();
    GsonFactory jsonFactory = new GsonFactory();
    GoogleCredential credential;
    Drive service = null;
    List<String> scopes = Arrays.asList(DriveScopes.DRIVE);
    try {
        credential = new GoogleCredential.Builder()
                .setTransport(httpTransport)
                .setJsonFactory(jsonFactory)
                .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
                .setServiceAccountScopes(scopes)
                .setServiceAccountPrivateKeyFromP12File(
                        new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
                .build();
        service = new Drive.Builder(httpTransport, jsonFactory, null).setApplicationName("MyAppName")
                .setHttpRequestInitializer(credential).build();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return service;
}
4

2 回答 2

1

实际上有两种方法可以通过 Drive Api 使用服务帐户进行身份验证。如果您使用 Dev App Server 在本地计算机上进行调试,则您使用的那个是可以的,但一旦部署到 GAE 就无法工作。您可以使用此代码片段进行身份验证,该代码片段取自 Drive API Reference on

https://developers.google.com/drive/service-accounts#google_app_engine_project_service_accounts

只需将您从控制台获取的 API Key 放入代码中即可。这是我为 Drive API 的 GAE 身份验证找到的唯一可行的解​​决方案。

这是您要添加到项目中的代码:

import com.google.api.client.googleapis.extensions.appengine.auth.oauth2.AppIdentityCredential;
import com.google.api.client.googleapis.services.CommonGoogleClientRequestInitializer;
import com.google.api.client.googleapis.services.GoogleClientRequestInitializer;
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.jackson.JacksonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
...

/** The API Key of the project */
private static final String API_KEY = "the_api_key_of_the_project";

/**
 * Build and returns a Drive service object authorized with the
 * application's service accounts.
 *
 * @return Drive service object that is ready to make requests.
 */
public static Drive getDriveService() throws GeneralSecurityException,
    IOException, URISyntaxException {
  HttpTransport httpTransport = new NetHttpTransport();
  JsonFactory jsonFactory = new JacksonFactory();
  AppIdentityCredential credential =
      new AppIdentityCredential.Builder(DriveScopes.DRIVE).build();
  GoogleClientRequestInitializer keyInitializer =
      new CommonGoogleClientRequestInitializer(API_KEY);
  Drive service = new Drive.Builder(httpTransport, jsonFactory, null)
      .setHttpRequestInitializer(credential)
      .setGoogleClientRequestInitializer(keyInitializer)
      .build();
  return service;
}
于 2013-09-25T12:18:06.290 回答
0

通常,要调试 Oauth,请打开日志记录并检查线路上发生了什么。显然,在本地和 GAE 上都这样做,您正在寻找差异。

由于两种环境的代码相同,因此这不是问题的可能根源。有些事情要检查...

  1. 您是否确认正确设置了范围、clientId 和私钥等内容
  2. 在您的代码中,凭证是空的,还是只有服务?
  3. 您的用户/凭据存储中是否缺少任何内容?
  4. 您管理用户会话的代码是否正常工作?
于 2013-09-25T09:19:22.193 回答