解决AWS Lambda@Edge授权代码体积超限(超1MB)问题求助
解决CloudFront Lambda@Edge代码体积超1MB限制的方案
针对你用authlib导致代码包超出CloudFront 1MB限制的问题,以下是对应你思路的具体实现方案,以及额外可行方案:
方案1:替换为轻量JWT库(优先级最高)
pyjwt是比authlib轻量得多的JWT处理库,核心包体积极小,搭配cryptography(或pyjwt[crypto])即可支持JWK验证,打包后轻松控制在1MB内。
替代代码示例:
import jwt from jwt import PyJWKClient import time def validate_jwt(token, issuer, audience, jwk_url): # 从JWK URL动态获取签名公钥 jwks_client = PyJWKClient(jwk_url) signing_key = jwks_client.get_signing_key_from_jwt(token) # 验证JWT及核心Claims try: payload = jwt.decode( token, signing_key.key, algorithms=["RS256"], # 根据你的实际签名算法调整 issuer=issuer, audience=audience, options={"verify_exp": True} # 强制验证过期时间 ) return payload except jwt.InvalidTokenError as e: raise Exception(f"Token validation failed: {str(e)}")
打包优化步骤:
- 执行
pip install pyjwt[crypto] --target ./package将依赖安装到指定目录 - 删除
package目录下的__pycache__、.dist-info、测试文件等冗余内容 - 将你的业务代码与
package目录一起压缩,最终体积通常在500KB以内
方案2:手动实现JWT验证(适合极致精简)
若不想依赖任何第三方库,可手动实现核心验证逻辑,但需严格遵循JWT标准,避免安全漏洞,仅推荐对JWT机制熟悉的场景。
核心实现代码(以RS256算法为例):
import base64 import hashlib import json import time from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives import serialization def base64url_decode(data): # 处理Base64URL的填充补全 padding = b'=' * (4 - len(data) % 4) return base64.urlsafe_b64decode(data + padding) def validate_jwt_manual(token, issuer, audience, jwk): header_b64, payload_b64, signature_b64 = token.split('.') header = json.loads(base64url_decode(header_b64)) payload = json.loads(base64url_decode(payload_b64)) signature = base64url_decode(signature_b64) # 验证基础Claims if payload.get('iss') != issuer: raise Exception("Invalid issuer") if payload.get('aud') != audience: raise Exception("Invalid audience") if payload.get('exp', 0) < time.time(): raise Exception("Token expired") # 从JWK构建公钥 public_key = serialization.load_der_public_key( base64url_decode(jwk['n']), backend=None ) # 验证签名 message = f"{header_b64}.{payload_b64}".encode() try: public_key.verify( signature, message, padding.PKCS1v15(), hashlib.sha256() ) return payload except: raise Exception("Invalid signature")
注意事项:
- 需根据实际使用的签名算法(如HS256、ES256)调整验证逻辑
- 必须严格验证所有必要Claims,避免逻辑漏洞
- 手动处理Base64URL解码时需注意填充补全问题
方案3:改用Node.js Lambda函数
Node.js的JWT生态库体积更小,打包后更容易满足1MB限制,比如jsonwebtoken搭配jwks-rsa即可实现完整验证逻辑。
代码示例:
const jwt = require('jsonwebtoken'); const jwksClient = require('jwks-rsa'); const client = jwksClient({ jwksUri: 'YOUR_JWK_ENDPOINT_URL' }); function getSigningKey(header, callback) { client.getSigningKey(header.kid, (err, key) => { const signingKey = key.getPublicKey(); callback(null, signingKey); }); } exports.handler = async (event) => { const token = event.headers.authorization?.split(' ')[1]; if (!token) { return { statusCode: 401, body: 'Unauthorized' }; } try { const payload = await new Promise((resolve, reject) => { jwt.verify(token, getSigningKey, { issuer: 'YOUR_ISSUER', audience: 'YOUR_AUDIENCE', algorithms: ['RS256'] }, (err, decoded) => { err ? reject(err) : resolve(decoded); }); }); return event; // 验证通过,放行请求 } catch (err) { return { statusCode: 403, body: 'Forbidden' }; } };
打包优化步骤:
- 执行
npm install jsonwebtoken jwks-rsa --production安装生产依赖 - 仅压缩
node_modules目录和你的业务代码文件,最终体积通常在300KB-800KB之间
额外可行方案:使用CloudFront Functions
如果你的授权逻辑足够简单(仅验证JWT签名和基础Claims),可改用CloudFront Functions,它的代码包限制为10KB,仅支持JavaScript,适合公钥固定、无需动态获取JWK的场景。
简化示例:
function handler(event) { const token = event.request.headers.authorization?.value.split(' ')[1]; if (!token) return { statusCode: 401 }; // 硬编码固定公钥(适合公钥长期不变的场景) const publicKey = '-----BEGIN PUBLIC KEY-----YOUR_PUBLIC_KEY_HERE-----END PUBLIC KEY-----'; try { const payload = jwtVerify(token, publicKey, { issuer: 'YOUR_ISSUER', audience: 'YOUR_AUDIENCE' }); return event.request; } catch (err) { return { statusCode: 403 }; } }
注意:CloudFront Functions不支持第三方库,需手动实现签名验证或硬编码公钥。
内容的提问来源于stack exchange,提问作者Frankster
相关产品推荐
相关产品推荐

