0

我有一个使用无服务器 NextJS 构建并在 AWS CloudFront 后面提供服务的 React 应用程序。我还使用 AWS Cognito 对我们的用户进行身份验证。

在用户通过 AWS Cognito 成功进行身份验证后,他们将被重定向到我的 React 应用程序,并使用包含 OAuth 令牌 ( id_token, access_token, refresh_token, raw[id_token], raw[access_token], raw[refresh_token], raw[expires_in], raw[token_type]) 的查询字符串。

查询字符串似乎只是大于 AWS CloudFront 的限制,并且在下面抛出以下错误:

413 ERROR
The request could not be satisfied.

Bad request. We can't connect to the server for this app...

Generated by cloudfront (CloudFront)
Request ID: FlfDp8raw80pAFCvu3g7VEb_IRYbhHoHBkOEQxYyOTWMsNlRjTA7FQ==

许多其他用户以前遇到过此错误(请参见示例)。想知道:

  • 有什么解决方法吗?也许有一种方法可以配置 AWS Cognito 以减少默认情况下它在查询字符串中传递的令牌数量?

  • 是否可以将 AWS CloudFront 配置为忽略对某些页面(而不是缓存主题)强制执行其默认限制?

  • 下一步有什么建议?我唯一能想到的就是使用 AWS CloudFront。

4

1 回答 1

1

在分析 AWS Cognito 发送到回调 URL 的查询字段后,我能够确定我的用例并非所有字段都是必需的。特别是rawOAuth 令牌字段。

有了这些信息,我通过编写一个“中间件”来拦截我的后端系统重定向到我的前端(位于 CloudFront 后面)并修剪掉我不需要完成身份验证的查询字符串字段,从而解决了这个问题。

如果这可能会激发其他人遇到类似问题,这是我的中间件在我的后端系统(Strapi)中的样子:

module.exports = (strapi) => {
  return {
    initialize() {
      strapi.app.use(async (ctx, next) => {
        await next();

        if (ctx.request.url.startsWith("/connect/cognito/callback?code=")) {
          // Parse URL (with OAuth query string) Strapi is redirecting to
          const location = ctx.response.header.location;
          const { protocol, host, pathname, query } = url.parse(location);

          // Parse OAuth query string and remove redundant (and bloated) `raw` fields
          const queryObject = qs.parse(query);
          const trimmedQueryObject = _.omit(queryObject, "raw");

          // Reconstruct original redirect Url with shortened query string params
          const newLocation = `${protocol}//${host}${pathname}?${qs.stringify(
            trimmedQueryObject
          )}`;

          ctx.redirect(newLocation);
        }
      });
    },
  };
};

于 2020-12-07T10:57:16.180 回答