更快的API,更高效的开发者:API Gateway自定义授权器

作者:API传播员 · 2026-01-12 · 阅读时间:6分钟

在上一篇关于加速 AWS Lambda 延迟的文章中,我们通过 AWS Lambda、无服务器架构中的优势。


什么是 AWS API Gateway 自定义授权器?

在构建新的 AWS API Gateway 自定义授权器及其优势。自定义授权器允许开发者定义一个 Lambda 函数,在请求到达服务 Lambda 或其他 AWS 资源之前执行。该函数可以检查入站请求,执行身份验证和授权逻辑,并动态生成访问策略。根据验证结果,授权器可以允许请求继续或直接拒绝。

通过将验证逻辑封装到自定义授权器中,可以实现以下优势:

  • 创建干净、可重用的验证模式。
  • 将验证逻辑独立为组件,减少重复工作。
  • 提升服务团队开发效率,同时降低因不同实现方式导致的安全风险。

更多关于 AWS API Gateway 自定义授权器的详细信息,可以参考 Alex DeBrie 的研究。


构建新的 API 端点

要新增头像图片的 API 端点,我们需要先修改用户模型,增加一个可选的 profile_pic 属性:

interface User {
  id: string;
  name: string;
  followers: Array;
  profile_pic?: string;
}

接着,我们更新 /bootstrap 端点,使其随机生成用户的头像图片,并将其作为 Base64 编码字符串存储在 DynamoDB 中。现有的 /users/:id/cached-users/:id 端点将保持轻量化,仅返回用户的 idnamefollowers 信息。

新增的两个端点如下:

  • /profile-pic/:id:返回指定用户的 Base64 编码头像图片。
  • /cached-profile-pic/:id:通过缓存加速返回用户头像。

添加 API Gateway 自定义授权器

在服务能够处理新端点后,我们需要通过 AWS API Gateway 将其公开给用户。在此之前,需要编写一个自定义授权器 Lambda 函数。以下是自定义授权器的代码示例

const generateAuthorizerResponse = (
principalId: string,
effect: string,
resource: string,
context: any
) => ({
principalId,
policyDocument: {
Version: "2012-10-17",
Statement: [
{
Action: "execute-api:Invoke",
Effect: effect,
Resource: resource,
},
],
},
context,
});

const ALLOW = "Allow";
const DENY = "Deny";
const ur = new DefaultClient(new UsersDdb());

export const handler = async (event: AuthorizerRequest): Promise => {
const methodArn = event.methodArn;
try {
return await customAuthLogic(
event.headers["Authorization"],
methodArn,
event.pathParameters["id"]
);
} catch (error) {
console.error(Authorization error: ${JSON.stringify(error)}); throw new Error("Internal Server Error"); } }; const customAuthLogic = async ( authToken: string, methodArn: string, requestedUserId: string ) => { const user = process.env["CACHE_ENABLED"] === "true" ? await ur.getCachedUser(requestedUserId) : await ur.getUser(requestedUserId); if (!user) { throw new Error(User not found: ${requestedUserId}); } if (user.followers.indexOf(authToken) < 0) { console.info(Unauthorized access attempt by ${authToken}); return generateAuthorizerResponse(authToken, DENY, methodArn, {}); } console.info(Authorized access by ${authToken}); return generateAuthorizerResponse(authToken, ALLOW, methodArn, { id: authToken }); }; const generateAuthorizerResponse = ( principalId: string, effect: string, resource: string, context: any ) => ({ principalId, policyDocument: { Version: "2012-10-17", Statement: [ { Action: "execute-api:Invoke", Effect: effect, Resource: resource, }, ], }, context, });

通过上述代码,我们可以根据是否启用缓存,动态决定从缓存还是 DynamoDB 获取用户数据。

接下来,我们使用 AWS CDK 将自定义授权器与 API 路由连接起来。以下是缓存和非缓存端点的配置示例:

// 启用缓存的自定义授权器
const customAuthLambdaWithCache = new NodejsFunction(this, "CustomAuthFunctionWithCache", {
  entry: join(__dirname, "../../src/functions", "isFollowerAuthorizer.ts"),
  environment: { "CACHE_ENABLED": "true" },
});

// 禁用缓存的自定义授权器
const customAuthLambdaNoCache = new NodejsFunction(this, "CustomAuthFunctionNoCache", {
  entry: join(__dirname, "../../src/functions", "isFollowerAuthorizer.ts"),
  environment: { "CACHE_ENABLED": "false" },
});// 配置 API 路由
api.root.addResource("profile-pic").addResource("{id}").addMethod("GET", svcLambdaIntegration, {
  authorizationType: AuthorizationType.CUSTOM,
  authorizer: new RequestAuthorizer(this, "IsFollowerAuthorizerNoCache", {
    handler: customAuthLambdaNoCache,
  }),
});api.root.addResource("cached-profile-pic").addResource("{id}").addMethod("GET", svcLambdaIntegration, {
  authorizationType: AuthorizationType.CUSTOM,
  authorizer: new RequestAuthorizer(this, "IsFollowerAuthorizerWithCache", {
    handler: customAuthLambdaWithCache,
  }),
});

测试端点

以下是测试新端点的示例:

  1. 获取用户基本信息:

    curl -s https://example.com/prod/users/0 | jq
  2. 测试授权器:

    • 授权成功:

      curl -s -o /dev/null -w "nStatus: %{http_code}n" -H "Authorization: 22" https://example.com/prod/profile-pic/0
    • 授权失败:

      curl -s -o /dev/null -w "nStatus: %{http_code}n" -H "Authorization: 44" https://example.com/prod/profile-pic/0

性能评估

为了评估性能,我们对两个端点分别执行 100 次请求,并记录延迟数据。以下是测试结果:

无缓存:

for i in $(seq 1 100); do
  curl -o /dev/null -H "Authorization: 22" https://example.com/prod/profile-pic/0
done

带缓存:

for i in $(seq 1 100); do
  curl -o /dev/null -H "Authorization: 22" https://example.com/prod/cached-profile-pic/0
done

根据 CloudWatch 的自定义指标,启用缓存后,API 的平均响应时间和 P99 延迟显著降低。


总结

通过为新的头像图片 API 添加自定义授权器和缓存,我们显著提升了服务的性能和安全性。API Gateway 自定义授权器不仅简化了身份验证逻辑,还提高了开发效率。结合 Momento 缓存,无服务器架构能够更好地满足高性能需求,为用户提供快速响应的体验。

原文链接: https://www.gomomento.com/blog/faster-apis-faster-developers-api-gateway-custom-authorizers/