共计 2554 个字符,预计需要花费 7 分钟才能阅读完成。
背景痛点:静态 API Key 的安全困境
在开放 API 场景中,传统静态 API Key 存在几个致命缺陷:

- 长期有效性问题 :一旦泄露,攻击者可以无限期使用直到手动撤销
- 缺乏细粒度控制 :无法针对不同客户端或会话设置差异化权限
- 难以追溯 :同一个 Key 可能被多人共享,难以定位具体责任人
- 防重放攻击弱 :简单的请求复制就能实现恶意调用
典型的安全事件包括 GitHub API 密钥泄露导致代码库被清空、AWS Access Key 泄露引发的挖矿攻击等。
技术方案对比
| 方案 | 适用场景 | 安全性 | 管理复杂度 |
|---|---|---|---|
| JWT | 短期会话认证 | 依赖签名算法强度 | 中 |
| OAuth2.0 | 第三方授权 | 流程复杂但较完善 | 高 |
| AWS WAF Token | API 网关防护 | 基础设施级防护 | 低 |
AWS WAF Token 的核心优势在于:
- 与 CloudFront 深度集成,无需改造业务代码
- 令牌生命周期可精确到秒级
- 防御规则可与其他 WAF 能力(如 IP 黑白名单)叠加
核心实现
令牌生成 / 验证流程
sequenceDiagram
Client->>Lambda: 请求生成 Token(带时间戳)Lambda->>KMS: 调用加密签名
Lambda-->>Client: 返回 Token(含 expires 字段)
Client->>API Gateway: 携带 Token 的请求
API Gateway->>WAF: 验证 Token 有效性
WAF-->>API Gateway: 验证结果
alt 验证通过
API Gateway->>Backend: 转发请求
else 验证失败
API Gateway-->>Client: 403 Forbidden
end
Terraform 部署模板
# WAF 规则组定义
resource "aws_wafv2_web_acl" "api_protection" {
name = "api-token-acl"
scope = "REGIONAL"
description = "Token validation rule set"
default_action {allow {}
}
rule {
name = "token-validation"
priority = 1
action {block {}
}
statement {
byte_match_statement {
field_to_match {
single_header {name = "X-API-Token"}
}
positional_constraint = "EXACTLY"
search_string = var.expected_token
text_transformation {
priority = 0
type = "NONE"
}
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "TokenValidation"
sampled_requests_enabled = true
}
}
}
# 关键 IAM 权限(最小化原则)resource "aws_iam_role_policy" "token_generator" {
name = "token-generator-policy"
role = aws_iam_role.lambda_exec.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{Action = ["kms:Sign"]
Effect = "Allow"
Resource = aws_kms_key.token_signer.arn
}
]
})
}
性能优化
Lambda 冷启动应对
- 预热策略 :
- 配置 CloudWatch Events 每分钟触发一次
-
使用 Provisioned Concurrency 保持 1 个实例常驻
-
内存配置 :
- 测试数据显示 256MB 内存时冷启动约 1200ms
- 提升到 1024MB 后降至 400ms(KMS 操作不受内存影响)
WAF 规则基准测试
| 测试场景 | 平均延迟 | P99 延迟 | 吞吐量 (RPS) |
|---|---|---|---|
| 无 WAF | 28ms | 51ms | 12,000 |
| 基础规则集 | 31ms | 55ms | 11,800 |
| 添加 Token 验证 | 33ms | 58ms | 11,500 |
| 全规则集 + 速率限制 | 36ms | 62ms | 10,200 |
避坑指南
Token 与 CDN 缓存
- 缓存键设计 :确保 Vary 头包含
X-API-Token - 过期协调 :Token 有效期应短于 CDN 缓存时间(推荐比例 1:3)
防爆破配置
rule {
name = "rate-limiting"
priority = 2
action {block {}
}
statement {
rate_based_statement {
limit = 100 # 每秒请求数
aggregate_key_type = "IP"
}
}
}
代码示例(Python)
import boto3
from datetime import datetime, timedelta
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
kms = boto3.client('kms')
def generate_token(event, context):
try:
# 有效期为当前时间 + 5 分钟
expires = int((datetime.now() + timedelta(minutes=5)).timestamp())
# 使用 KMS 签名
response = kms.sign(
KeyId='alias/token-signer-key',
Message=str(expires).encode(),
MessageType='RAW',
SigningAlgorithm='RSASSA_PSS_SHA_256'
)
return {'token': f"{expires}:{response['Signature'].hex()}",
'expires': expires
}
except Exception as e:
logger.error(f"Token generation failed: {str(e)}")
raise
延伸思考
更高级的实现可以考虑:
- 动态令牌 :结合 KMS 数据密钥加密,每次生成唯一 Token
- 属性加密 :在 Token 中嵌入用户角色等属性,由 WAF 做初步鉴权
- 双向验证 :客户端验证服务端证书防止中间人攻击
安全是一个持续的过程,建议定期:
- 轮换 KMS 密钥(每年至少一次)
- 审计 WAF 规则阻止的请求
- 监控 Token 使用模式异常
正文完
