使用登录用户的idToken调用Google Drive API

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

我想使用我的 Spring Boot java 应用程序列出 Google Drive 上已登录用户的文件。

我已经实现了 Google 登录流程,效果很好。我在登录时要求用户允许访问他/她的 Google 云端硬盘。 在控制器方法中,我访问用户的 idToken。 目的是我重用此令牌并将其传递给 Google Drive API 调用,但 API 拒绝此令牌。 API 返回并显示以下错误:

{
  ...

  "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
  
  ...
}

看起来我无法重复使用这个idToken。我想,我将需要另一种类型的令牌,但无法弄清楚,是什么样的,以及如何。有人可以建议吗?

以下是我测试时使用的控制器方法:

    @GetMapping("")
    public ResponseEntity<List<String>> listFiles(Authentication authentication) throws IOException,
                                                                                        GeneralSecurityException {
        // get idToken of authenticated user
        OAuth2AuthenticationToken oauth2Auth = (OAuth2AuthenticationToken) authentication;
        String idToken = ((DefaultOidcUser) oauth2Auth.getPrincipal()).getIdToken().getTokenValue();
        Credentials credentials = IdTokenCredentials.create(AccessToken.newBuilder().setTokenValue(idToken).build());

        // Build the Drive service and list files.
        Drive service = new Drive.Builder(GoogleNetHttpTransport.newTrustedTransport(),
                                          new GsonFactory(),
                                          new HttpCredentialsAdapter(credentials)).setApplicationName(APPLICATION_NAME)
                                                                                  .build();
        FileList result = service.files().list().setPageSize(10).setFields("files(name)").execute();
        List<String> fileNames = result.getFiles().stream().map(file -> file.getName()).toList();
        return ResponseEntity.ok(fileNames);
    }

java spring-boot authentication google-drive-api drive
1个回答
0
投票

您需要使用 Spring 的 OAuth2AuthorizedClientService 将 ID 令牌交换为访问令牌。

private final OAuth2AuthorizedClientService clientService;

@GetMapping("")
public ResponseEntity<List<String>> listFiles(Authentication authentication) throws IOException,
                                                                                    GeneralSecurityException {
    // get idToken of authenticated user
    OAuth2AuthenticationToken oauthToken = (OAuth2AuthenticationToken) authentication;

    OAuth2AuthorizedClient client =
        clientService.loadAuthorizedClient(
            oauthToken.getAuthorizedClientRegistrationId(),
            oauthToken.getName());

    String accessToken = client.getAccessToken().getTokenValue();

    Credentials credentials = IdTokenCredentials.create(AccessToken.newBuilder().setTokenValue(accessToken).build());

    // Build the Drive service and list files.
    Drive service = new Drive.Builder(GoogleNetHttpTransport.newTrustedTransport(),
                                      new GsonFactory(),
                                      new HttpCredentialsAdapter(credentials)).setApplicationName(APPLICATION_NAME)
                                                                              .build();
    FileList result = service.files().list().setPageSize(10).setFields("files(name)").execute();
    List<String> fileNames = result.getFiles().stream().map(file -> file.getName()).toList();
    return ResponseEntity.ok(fileNames);
}
© www.soinside.com 2019 - 2024. All rights reserved.