AWS API Gateway授权与架构:多客户端共用API搭建问询
多客户端API搭建方案建议
需求与现状梳理
核心需求
- 客户端配备带限流功能的API Key,用于创建使用计划
- API Key与数据库名称绑定,基于GoFiber实现服务逻辑
- 单个客户端可关联多个数据库,支持用独立API Key对应不同数据库
当前设计
采用路径模式:https://path-to-api.com/v1/:database/,将:database作为客户端数据库的根路径参数。纠结于两种权限校验方案:一是用API Gateway授权器验证客户端对指定数据库的访问权限;二是在GoFiber内部完成校验,不确定这种"单体化"方式是否适配Lambda部署场景,同时需要解决路径参数向Lambda上GoFiber实例的传递问题。
核心路由伪代码
package gofiberApp import ( "context" "fmt" "os" "github.com/gofiber/fiber/v2" ) func SetRoutes(app *fiber.App) { app.Get("/", func(c *fiber.Ctx) error { return c.JSON(fiber.Map{ "error": "Please choose a database", }) }) api := app.Group("/:database", func(c *fiber.Ctx) error { // Potentially run some checks here and connect to specific database return c.Next() }) api.Get("/", func(c *fiber.Ctx) error { return c.JSON(fiber.Map{ "message": "No action provided", }) }) api.Get("/outputs", func(c *fiber.Ctx) error { // Where we would run a SELECT query with c.Params() return c.SendString("Testing! 23") }) api.Post("/generate", func(c *fiber.Ctx) error { // Where we would either perform the action with c.Params() or call another lambda return c.SendString("Where we generate the output") }) }
最终目标
打造多客户端共享的API服务,客户端通过专属API Key访问对应数据库,无需为每个客户端单独创建部署阶段,示例访问路径:
- client 1:
https://path-to-gateway.com/v1/foo/outputs(带参数)- 对应API Key - client 2:
https://path-to-gateway.com/v1/bar/generate(带参数)- 对应API Key - client 1:
https://path-to-gateway.com/v1/baz/generate(带参数)- 对应API Key
方案选型与实现建议
1. 推荐:API Gateway授权器 + GoFiber轻量校验
这种分层校验模式更适配Lambda+API Gateway的Serverless架构:
- API Gateway层:负责API Key合法性校验、限流(直接用Gateway自带的使用计划功能,无需自研限流逻辑),解析路径参数
:database后,将API Key关联的可访问数据库列表传递给Lambda。 - GoFiber层:接收Gateway传递的权限数据,快速校验当前请求的
:database是否在允许范围内,同时完成对应数据库的连接逻辑。
优势:
- 复用Gateway原生能力处理限流和密钥验证,降低业务代码复杂度
- 分层校验提升安全性,即使GoFiber层出现漏洞,Gateway也能拦截非法请求
- 符合Serverless架构"前端路由过滤+后端业务处理"的分工逻辑
2. 不推荐:纯GoFiber内部校验
如果完全在GoFiber内处理密钥验证和权限检查,会带来以下问题:
- 需要自研限流逻辑,Serverless环境下还得依赖Redis等外部存储,维护成本高
- API Key直接暴露给Lambda,增加密钥泄露风险
- 无法利用Gateway的请求过滤、监控等原生能力
具体实现步骤
步骤1:配置API Gateway
- 创建API Key和使用计划,在API Key的自定义属性中绑定允许访问的数据库列表(或通过外部数据库存储关联关系)
- 配置自定义Lambda授权器,解析请求头中的API Key和路径参数
:database,校验该Key是否有权访问指定数据库,校验通过后将数据库权限信息注入请求上下文,传递给后端GoFiber服务
步骤2:GoFiber接收并校验上下文参数
在Lambda中,API Gateway会将授权器返回的上下文数据传递给GoFiber,可通过c.Locals()获取并校验:
api := app.Group("/:database", func(c *fiber.Ctx) error { // 从Gateway授权器传递的上下文中获取允许访问的数据库列表 allowedDatabases, ok := c.Locals("allowed_databases").([]string) if !ok { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ "error": "权限验证失败", }) } requestedDB := c.Params("database") // 校验当前请求的数据库是否在允许范围内 for _, db := range allowedDatabases { if db == requestedDB { // 复用连接池获取数据库连接 c.Locals("db_connection", getDBConnection(requestedDB)) return c.Next() } } return c.Status(fiber.StatusForbidden).JSON(fiber.Map{ "error": "无权访问该数据库", }) })
步骤3:数据库连接优化
Serverless环境下建议用连接池复用,避免每次请求创建新连接:
- 初始化全局连接池,按数据库名称管理不同的连接实例
- 在路由中间件中根据
:database参数获取对应连接,注入请求上下文
注意事项
- API Key安全:要求客户端在请求头(如
X-API-Key)中传递密钥,禁止在URL中暴露 - 限流策略:直接通过API Gateway的使用计划配置限流规则,无需自研
- 监控与日志:开启API Gateway和Lambda的日志功能,便于追踪请求和排查问题
内容的提问来源于stack exchange,提问作者Joel Hager
相关产品推荐
相关产品推荐

