【问题标题】:Google Java API for AuthorizationCodeInstalledApp for web application用于 Web 应用程序的 AuthorizationCodeInstalledApp 的 Google Java API
【发布时间】:2018-05-01 01:13:54
【问题描述】:

我对 API 文档和我的用例以及如何处理我的 Web 应用程序的授权令牌有些困惑。我有一个网络服务,用户登录到我的应用程序(不是谷歌应用程序),我需要他们提供我的服务(带有 Spring Boot 的 Java)授权来为 Youtube 上传。稍后,我需要能够使用该授权“离线”将视频上传到他们的频道,而无需登录到我的服务(“自动发布”类型的功能)。我尝试了许多方法,并且通常可以正常工作,但是在干净实施方面遇到了一些障碍:

        GoogleAuthorizationCodeFlow flow =
                new GoogleAuthorizationCodeFlow.Builder(
                        httpTransport, JSON_FACTORY, clientSecrets, scopes)
                        .setDataStoreFactory(dataStoreFactory)
                        .setAccessType("offline")
                        .build();

        credential = new AuthorizationCodeInstalledApp(
                flow, new LocalServerReceiver()).authorize("user");

生成带有 url 的控制台消息,以供用户在浏览器中打开。我希望用户实际上会被重定向。我不希望这是一个手动过程,我必须在控制台上,然后向用户提供从该过程返回的 url,以便他们在自己的浏览器中打开。据我了解,LocalServerReceiver 用于在用户授予授权后处理实际的访问令牌响应。我已经对此进行了详细研究,但在示例中找不到任何文档解决方案或任何内容,这些示例不会产生影响“将以下 url 粘贴到浏览器中......”的控制台消息和授权 url .

我尝试通过以下方式使用 GoogleAuthorizationCodeFlow:

        GoogleAuthorizationCodeFlow flow = (new GoogleAuthorizationCodeFlow.Builder(httpTransport, JSON_FACTORY, clientSecrets, scopes))
                .setDataStoreFactory(dataStoreFactory)
                .setAccessType("offline")
                .build();

        return flow.newAuthorizationUrl()
                .setScopes(scopes)
                .setAccessType("offline")
                .setClientId(clientSecrets.getDetails().getClientId())
                .setRedirectUri(redirectionUrl)
                .toString();

我把“/oauth2-callback”作为我的redirectionUrl,这工作(有点)。我让用户进入 Google 授权页面,他们对其进行了授权,然后我获得了一个指向我的“回调”端点(“/oauth2-callback”)的令牌,但该令牌似乎没有被完全授权。我可以将它存储在我的数据存储中,并在那里看到它,但是当我尝试离线使用它时,我收到授权错误。浏览更多文档后,我发现了用于处理发送回我的回调的令牌的剩余代码:

        GoogleTokenResponse response = flow.newTokenRequest(token)
                .setRedirectUri(redirectUrl).execute();

        Credential credential = flow.createAndStoreCredential(response, "user");

这个问题是我已经在我的回调端点中,这需要另一个redirectURL。在我执行此“newTokenRequest”之前,来自授权的令牌在离线模式下不起作用,这需要另一个重定向 URL。它似乎需要 flow.newAuthorizationUrl() 调用中的原始 redirectURL,但是当执行 newTokenRequest 时,它会再次调用该 URL,并且我最终会收到“令牌已赎回”错误。

在上述任一场景中,使用 AuthorizationCodeInstalledApp 或使用带有回调 url 的 flow.newAuthorizationUrl(),我使用 flow.newTokenRequest 和 flow.createAndStoreCredential 处理令牌,我确实获得了一个可以稍后脱机使用的凭据。但是我在任何一个中都无法获得流畅的用户体验。

我在我的场景中缺少什么?

【问题讨论】:

    标签: java oauth-2.0 google-api offline credentials


    【解决方案1】:

    根据你调用authorize方法后的文档,它调用onAuthorization方法,最终使用authorizationUrl调用browse方法来尝试自动打开浏览器。

    public static void browse(String url) {
    Preconditions.checkNotNull(url);
    // Ask user to open in their browser using copy-paste
    System.out.println("Please open the following address in your browser:");
    System.out.println("  " + url);
    // Attempt to open it in the browser
    try {
      if (Desktop.isDesktopSupported()) {
        Desktop desktop = Desktop.getDesktop();
        if (desktop.isSupported(Action.BROWSE)) {
          System.out.println("Attempting to open that address in the default browser now...");
          desktop.browse(URI.create(url));
        }
      }
    } catch (IOException e) {
      LOGGER.log(Level.WARNING, "Unable to open browser", e);
    } catch (InternalError e) {
      // A bug in a JRE can cause Desktop.isDesktopSupported() to throw an
      // InternalError rather than returning false. The error reads,
      // "Can't connect to X11 window server using ':0.0' as the value of the
      // DISPLAY variable." The exact error message may vary slightly.
      LOGGER.log(Level.WARNING, "Unable to open browser", e);
    }
    

    }

    它应该在尝试打开浏览器的 try 块内。寻找Desktop.isDesktopSuported and desktop.isSupported(Action.BROWSE) 对你运行程序的平台是正确的。

    编辑:以上示例取自 Gmail 服务,但所有 Google 产品 AFAIK 的 oauth 授权流程都相同。

    【讨论】:

    • 我的服务在服务器上的 tomcat 下运行。 Oracle Desktop 实用程序类是 awt 包的一部分,它“允许 Java 应用程序启动在本机桌面上注册的关联应用程序以处理 URI 或文件”。由于这是在服务器上运行的,用户通过浏览器会话通过 servlet 连接,这使得 AuthorizationCodeInstalledApp.authorize(),我认为没有可用的“本机”桌面,这就是为什么我得到控制台输出。可能我不能为此使用 AuthorizationCodeInstalledApp??
    • 上面的代码是为在客户端运行而设计的。当您运行它时,它会尝试打开浏览器,但由于您在服务器上运行它,因此没有显示浏览器。如果您在服务器端调用它,您如何将结果传递给客户端?如果用户通过浏览器连接到您的系统,您可以更改设计以在客户端运行此授权过程。
    • 那是我的“路径 2”。在我对初始帖子的叙述中,从“我尝试使用 GoogleAuthorizationCodeFlow with:...”开始。我去获取授权 url 并将用户重定向到它,这很有效。但是 authcode 的后续处理会导致回调 url 的第二次命中,让我很伤心。这就是我现在的重点。
    猜你喜欢
    • 2018-05-26
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多