0

我正在使用无服务器堆栈,现在尝试添加 Lambda 自定义身份验证器以使用 Auth0 验证授权令牌,并在身份验证通过时将自定义数据添加到我的请求上下文中。

此时一切正常,除了当我缓存同一个令牌的 Authenticator 响应时。

我正在使用 5 秒缓存进行开发。具有有效令牌的第一个请求按原样通过。5 秒窗口中的下一个请求失败,出现一个神秘的 500 错误,而从未到达我的代码。

授权人配置

// MyStack.ts

const authorizer = new sst.Function(this, "AuthorizerFunction", {
    handler: "src/services/Auth/handler.handler",
});

const api = new sst.Api(this, "MarketplaceApi", {
  defaultAuthorizationType: sst.ApiAuthorizationType.CUSTOM,
  defaultAuthorizer: new HttpLambdaAuthorizer("Authorizer", authorizer, {
    authorizerName: "LambdaAuthorizer",
    resultsCacheTtl: Duration.seconds(5), // <-- this is the cache config
  }),
  routes: {
    "ANY /{proxy+}": "APIGateway.handler",
  },
});

授权处理程序

const handler = async (event: APIGatewayAuthorizerEvent): Promise<APIGatewayAuthorizerResult> => {
  // Authenticates with Auth0 and serializes context data I wanna
  // forward to the underlying service
  const authentication = await authenticate(event);
  const context = packAuthorizerContext(authentication.value);

  const result: APIGatewayAuthorizerResult = {
    principalId: authentication.value?.id || "unknown",
    policyDocument: buildPolicy(authentication.isSuccess ? "Allow" : "Deny", event.methodArn),
    context, // context has the following shape:
    // {
    //   info: {
    //     id: string,
    //     marketplaceId: string,
    //     roles: string,
    //     permissions: string
    //   }
    // }
  };

  return result;
};

CloudWatch 日志

在此处输入图像描述

☝️ 每个未缓存的请求都会成功,状态码为 200,集成 ID 和一切,正如它应该的那样。5 秒缓存期间的所有其他请求都会失败,并显示 500 错误代码并且没有集成 ID,这意味着它无法到达我的代码。


有小费吗?

更新

我刚刚在api-gateway.d.ts@types 文件中找到了这个(请注意评论):

// Poorly documented, but API Gateway will just fail internally if
// the context type does not match this.
// Note that although non-string types will be accepted, they will be
// coerced to strings on the other side.
export interface APIGatewayAuthorizerResultContext {
    [name: string]: string | number | boolean | null | undefined;
}

在我让授权人首先工作之前,我确实遇到了这个问题。我将我的rolespermissions属性作为字符串数组,我必须将它们转换为纯字符串。然后它起作用了。

瞧,我现在刚刚运行了一个测试,删除了我为成功验证的令牌返回的上下文信息,现在缓存在 每个请求成功时都在工作,但我确实需要我的上下文信息......

也许上下文对象有一个最大长度?请让我知道对上下文对象的任何限制。正如@types 文件所述,这件事的文档记录很差。这是我知道的文档。

4

1 回答 1

1

问题是任何上下文对象值都不能包含“特殊”字符。

您的上下文对象必须类似于:

"context": {
  "someString": "value",
  "someNumber": 1,
  "someBool": true
},

您不能将 JSON 对象或数组设置为上下文映射中任何键的有效值。唯一有效的值类型是字符串、数字和布尔值

不过,就我而言,我需要发送一个字符串数组。

我试图通过对数组进行 JSON 序列化来绕过类型限制,但"[\"valueA\",\"valueB\"]"由于某种原因,AWS 不喜欢它。

TL;博士

解决我的问题的是使用myArray.join(",")而不是JSON.stringify(myArray)

于 2022-02-28T20:57:33.860 回答