更快的API,更高效的开发者:API Gateway自定义授权器
在上一篇关于加速 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 端点将保持轻量化,仅返回用户的 id、name 和 followers 信息。
新增的两个端点如下:
/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,
}),
});
测试端点
以下是测试新端点的示例:
-
获取用户基本信息:
curl -s https://example.com/prod/users/0 | jq -
测试授权器:
-
授权成功:
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/
最新文章
- 为API网关构建ChatGPT自定义插件 – API7.ai
- 更快的API,更高效的开发者:API Gateway自定义授权器
- 如何使用 node.js 和 express 创建 rest api
- 2025年暑假大学生AI副业+联盟营销指南:自动化文章与链接实现月入过万
- 如何在Python中使用ChatGPT API?
- FastAPI 异步编程:提升 API 性能
- 什么是 LangChain
- Google News API 的热门话题与趋势分析
- GraphQL API渗透测试指南
- GitHub Copilot API接入指南
- 如何创建带有JSON响应的简单REST API
- 一文讲透MCP的原理及实践