简体   繁体   English

Java: Google AppEngine: OAuth: Google Drive API 访问用户的 Google Drive 内容由 ZC6E190B28404633333333333

[英]Java : Google AppEngine : OAuth : Google Drive API to access user's Google Drive contents created by Web Application

Scenario: I am working on a Web Application on Google AppEngine where users have to access files from their own Google Drive.场景:我正在 Google AppEngine 上开发 Web 应用程序,用户必须从他们自己的 Google Drive 访问文件。 I have looked for online help and this is what I have figured out.我一直在寻找在线帮助,这就是我想出的。

I have used this link for help that worked fine while testing with local machine https://github.com/gsuitedevs/java-samples/blob/master/drive/quickstart/src/main/java/DriveQuickstart.java我已使用此链接寻求帮助,在使用本地机器https://github.com/gsuitedevs/java-samples/blob/master/drive/quickstart/src/main/java/DriveQuickstart.java进行测试时效果很好

Step 1 (Seemed simple): Enable Google Drive API and Setup necessary credential, ie OAuth 2.0 Client ID for Web Application.第 1 步(看似简单):启用 Google Drive API 并设置必要的凭据,即 OAuth 2.0 客户端 ID 用于 Web 应用程序。 (This is done while enabling IAP on Google AppEngine, so I did not do it again. Whenever anyone opens the web application, he/she is asked to authenticate via iap.googleapis.com and details saved. This works fine). (这是在 Google AppEngine 上启用 IAP 时完成的,所以我没有再这样做。每当有人打开 web 应用程序时,都会要求他/她通过 iap.googleapis.com 进行身份验证并保存详细信息。这工作正常)。 Also, I have added Google Drive Scopes to the OAuth consent screen (../auth/drive.appdata &../auth/drive.file) that don't need verification by Google.此外,我已将 Google Drive Scopes 添加到不需要 Google 验证的 OAuth 同意屏幕 (../auth/drive.appdata &../auth/drive.file)。

Step 2 : Downloaded the credentials.json from OAuth Client ID and stored inside "resources" folder created in the root of application package (inside main folder, next to java and webapp folders) Step 2 : Downloaded the credentials.json from OAuth Client ID and stored inside "resources" folder created in the root of application package (inside main folder, next to java and webapp folders)

Step 3 : I have created a testing class (GoogleDriveServiceTest.class) that includes following code:第 3 步:我创建了一个包含以下代码的测试 class (GoogleDriveServiceTest.class):

String USER_ID1 = UserServiceFactory.getUserService().getCurrentUser().getUserId();
List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE_METADATA_READONLY);
NetHttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
InputStream inputStream = 
       GoogleDriveServiceTest.class.getResourceAsStream("/credentials.json");
if (inputStream == null) 
    throw new FileNotFoundException("Required credentials file not found");
GoogleClientSecrets googleClientSecrets = 
            GoogleClientSecrets.load(jsonFactory, new InputStreamReader(inputStream));
    
AppEngineDataStoreFactory appEngineDataStoreFactory = 
                              AppEngineDataStoreFactory.getDefaultInstance();

//IS SOMETHING MISSING HERE???
    
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow
                    .Builder(httpTransport, jsonFactory, googleClientSecrets, SCOPES)
                    .setDataStoreFactory(appEngineDataStoreFactory)
                    .setAccessType("offline")
                    .build();

Now I am trying to create the credential to be used for accessing Google Drive with this line:现在我正在尝试使用以下行创建用于访问 Google Drive 的凭据:

Credential credential = flow.loadCredential(USER_ID1);

that is returning null.即返回 null。

In my opinion I am missing to assign the credentials to AppEngineDataStoreFactory based on what I have seen in the example from the github link above.在我看来,根据我在上面的 github 链接的示例中看到的内容,我缺少将凭据分配给 AppEngineDataStoreFactory。 However, I am not sure if this is the issue, and if it is, how do I resolve it.但是,我不确定这是否是问题,如果是,我该如何解决。

Is there a straight forward way to assign credentials using logged in userID obtained from UserServiceFactory.getUserService().getCurrentUser().getUserId()?是否有一种直接的方法可以使用从 UserServiceFactory.getUserService().getCurrentUser().getUserId() 获得的登录用户 ID 分配凭据? Or should I be obtaining accetoken and create the credential?或者我应该获得 accetoken 并创建凭证? if so, how?如果是这样,怎么做?

(I don't want to use javascript as the same does not seem suitable for web application) (我不想使用 javascript,因为它似乎不适合 web 应用程序)

Any help would be great!!!!任何帮助都会很棒!!!!

PS: I also wanted to add a point that user needs to access only files added by the same web application either via web or from android PS:我还想补充一点,用户只需通过 web 或 android 访问由同一 web 应用程序添加的文件

Update #1 responding to @Aerials: Here is the code I was trying with to get the TokenResponse:更新 #1响应 @Aerials:这是我尝试获取 TokenResponse 的代码:

VerificationCodeReceiver receiver = new GooglePromptReceiver();
(I know above one is not the right option, but I am not able to find any other)    
AuthorizationCodeRequestUrl authorizationUrl =                          
        flow.newAuthorizationUrl().setRedirectUri(receiver.getRedirectUri());
String code = receiver.waitForCode();
(Above line returns: java.util.NoSuchElementException: No line found)
TokenResponse tokenResponse = 
            flow.newTokenRequest(code).setRedirectUri(redirectUri).execute();

Update #2 Code that worked in getting the TokenResponse and rest of the tasks of creating a Credential and connect to Google Drive successfully:更新 #2代码,用于获取创建凭据并成功连接到 Google Drive 的任务的 TokenResponse 和 rest:

GenericUrl genericUrl = new GenericUrl(request.getRequestURL().toString());
genericUrl.setRawPath("/googleDriveTest");
String redirectUri = genericUrl.build();

(redirectUri should match with authorised redirect URI inside OAuth ClientID under GCP API Credentials. If you added it now, you need to redownload the credentials.json file) (redirectUri 应与 GCP API Credentials 下 OAuth ClientID 内的授权重定向 URI 匹配。如果现在添加,则需要重新下载 credentials.Z466DEEC76ECDF5FCA6D38571F6324D54 文件)

String redirectUrl =  authorizationCodeFlow
                            .newAuthorizationUrl()
                            .setRedirectUri(redirectUri)
                            .build();
String authorizationCode = request.getParameter("code");
if (authorizationCode == null || authorizationCode.isEmpty())
              response.sendRedirect(redirectUrl);
TokenResponse tokenResponse = authorizationCodeFlow
                                    .newTokenRequest(authorizationCode)
                                    .setRedirectUri(redirectUri).execute();
authorizationCodeFlow.createAndStoreCredential(tokenResponse, USER_ID1);
Credential credential = authorizationCodeFlow.loadCredential(USER_ID1);
Drive service = new Drive.Builder(httpTransport, jsonFactory, credential)
                         .setApplicationName("myapplicationname")
                         .build();

You need to first create and store the credentials in the flow's credential store:您需要首先创建凭据并将其存储在流的凭据存储中:

createAndStoreCredential(TokenResponse response, String userId)

to be able to load them with loadCredential(String userId)能够使用loadCredential(String userId)加载它们

The loadCredential() method will return credential found in the credential store of the given user ID or null for none found. loadCredential()方法将返回在给定用户 ID 的凭证存储中找到的凭证,或者返回 null (未找到)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM