【问题标题】:Web application deployed not generating authorization tokens部署的 Web 应用程序未生成授权令牌
【发布时间】:2021-03-25 01:46:59
【问题描述】:

我正在尝试使用带有 oauth2 凭据的 gmail api 发送,如下所示

private Credential getCredentials(NetHttpTransport httpTransport) throws IOException {
        // Load client secrets.
        try {
            Resource file = resourceLoader.getResource("classpath:credentials.json");
            InputStream inputStream = file.getInputStream();
            GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,
                    new InputStreamReader(inputStream));
            // Build flow and trigger user authorization request.
            GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(httpTransport, JSON_FACTORY,
                    clientSecrets, SCOPES)
                            .setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
                            .setAccessType("offline").build();

            return new AuthorizationCodeInstalledApp(flow,  new LocalServerReceiver()).authorize("user");
        } catch (Exception exception) {
            exception.printStackTrace();
            LOGGER.info("Exception occured:: {}", exception.getMessage());
            throw new RecordNotFoundException(exception.getMessage());
        }

    }

使用桌面应用的 credentials.json 文件。

当我在开发服务器中部署后,我无法生成访问和刷新令牌保存的文件。

你能帮帮我吗?

【问题讨论】:

  • 请编辑您的问题并包含您可能收到的任何错误消息。并定义无法生成的含义。

标签: java google-api google-oauth gmail-api google-api-java-client


【解决方案1】:

AuthorizationCodeInstalledApp OAuth 2.0 授权代码流,用于保存最终用户凭据的已安装 Java 应用程序。

你不能将它部署到服务器上,因为它会在服务器上打开授权窗口。

对于网络应用程序,您应该关注Oauth

public class CalendarServletSample extends AbstractAuthorizationCodeServlet {

  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws IOException {
    // do stuff
  }

  @Override
  protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
    GenericUrl url = new GenericUrl(req.getRequestURL().toString());
    url.setRawPath("/oauth2callback");
    return url.build();
  }

  @Override
  protected AuthorizationCodeFlow initializeFlow() throws IOException {
    return new GoogleAuthorizationCodeFlow.Builder(
        new NetHttpTransport(), JacksonFactory.getDefaultInstance(),
        "[[ENTER YOUR CLIENT ID]]", "[[ENTER YOUR CLIENT SECRET]]",
        Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(
        DATA_STORE_FACTORY).setAccessType("offline").build();
  }

  @Override
  protected String getUserId(HttpServletRequest req) throws ServletException, IOException {
    // return user ID
  }
}

public class CalendarServletCallbackSample extends AbstractAuthorizationCodeCallbackServlet {

  @Override
  protected void onSuccess(HttpServletRequest req, HttpServletResponse resp, Credential credential)
      throws ServletException, IOException {
    resp.sendRedirect("/");
  }

  @Override
  protected void onError(
      HttpServletRequest req, HttpServletResponse resp, AuthorizationCodeResponseUrl errorResponse)
      throws ServletException, IOException {
    // handle error
  }

  @Override
  protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
    GenericUrl url = new GenericUrl(req.getRequestURL().toString());
    url.setRawPath("/oauth2callback");
    return url.build();
  }

  @Override
  protected AuthorizationCodeFlow initializeFlow() throws IOException {
    return new GoogleAuthorizationCodeFlow.Builder(
        new NetHttpTransport(), JacksonFactory.getDefaultInstance()
        "[[ENTER YOUR CLIENT ID]]", "[[ENTER YOUR CLIENT SECRET]]",
        Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(
        DATA_STORE_FACTORY).setAccessType("offline").build();
  }

  @Override
  protected String getUserId(HttpServletRequest req) throws ServletException, IOException {
    // return user ID
  }
}

【讨论】:

  • 您好 DalmTo,我不希望我的用户使用 google 登录,我只想使用 java 使用 oauth2 发送电子邮件,而无需在 google 中打开不太安全的应用程序。
  • 除非您有 gsuite 域并且可以将域范围的委派设置为服务帐户。有人将必须登录才能使其正常工作。您需要以用户身份登录才能访问用户的 gmail 帐户。
  • 我已允许使用 gmail 帐户的应用程序发送访问我的 gmail 范围,我可以从本地发送电子邮件,但在部署中会生成 url,但我无法使用该重定向 url 提供访问权限。
  • 这也是因为您正在使用已安装应用程序的代码。如果您想托管它,那么您必须将其设置为 Web 应用程序,以便您可以登录。您无法从服务器登录,因为它试图在服务器而不是客户端计算机上生成 Web 浏览器。
  • 你有工作代码sn-p吗,对我来说看起来很复杂。
【解决方案2】:

根据我从您的问题和 cmet 中了解到的情况,您希望实现以下目标:

使用您当前的代码从您的应用程序发送电子邮件消息,该应用程序已经在您的本地计算机上运行,​​现在您也想在 Web 服务器中执行此操作。

考虑到您是唯一需要授权应用程序的用户,您可以使用service accounts 实现您的目标。

服务帐户最适合像您这样的应用程序,您不需要用户授权,而是需要您的帐户授权,例如自动发送电子邮件。

这些类型的帐户属于您的应用程序而不是单个用户,并且可以发出 API 请求而无需通过 UI 进行授权。 This guide from the documentation 将逐步指导您如何使用服务帐户设置授权。

此外,请记住,为了让服务帐户以您的名义执行请求(因为您需要用户发送电子邮件),您应该使用 domain-wide authorization 以便服务帐户可以以用户。另请注意,您需要一个 Google Workspace 帐户来实施域范围的授权(如果您没有,请告诉我,因为我可以提出解决方法)

【讨论】:

  • 感谢您的回复,能否请您分享任何代码sn-p。我只想使用 gmail api 向用户发送电子邮件,而无需打开不太安全的应用程序
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-10
  • 2016-05-17
  • 2019-05-12
  • 1970-01-01
  • 1970-01-01
  • 2021-01-05
相关资源
最近更新 更多