Lambda@Edge无法获取Authorization请求头的问题求助
我编写了一个Node.js 20.x版本的Lambda函数,用于控制以S3为源的CloudFront分发静态网站的访问权限。目前index.mjs中的函数始终返回401状态码,并将event结构输出到响应体中:
export const handler = async (event, context) => { const request = event.Records[0].cf.request; const headers = request.headers; return { status: '401', statusDescription: 'Unauthorized', body: 'Unauthorized!\n' + JSON.stringify(event), headers: { 'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}] }, }; };
问题在于,尽管浏览器已发送Authorization请求头,但该头并未出现在event中。我尝试将函数关联到"Viewer Request"和"Origin Request"事件,结果一致。两年前我曾使用完全相同的配置搭配另一组S3和CloudFront,当时可以正常工作。对比两个CloudFront分发的配置后,未发现明显差异。
如何让我的Lambda函数获取到Authorization请求头?
以下是通过aws cloudfront get-distribution-config --id=DISTRIBUTION-ID获取的分发配置:
{ "ETag": "DISTRIBUTION-ID", "DistributionConfig": { "CallerReference": "some-uuid", "Aliases": { "Quantity": 1, "Items": [ "problem.example.com" ] }, "DefaultRootObject": "index.html", "Origins": { "Quantity": 1, "Items": [ { "Id": "problem.example.com.s3.us-east-1.amazonaws.com", "DomainName": "problem.example.com.s3.us-east-1.amazonaws.com", "OriginPath": "", "CustomHeaders": { "Quantity": 0 }, "S3OriginConfig": { "OriginAccessIdentity": "origin-access-identity/cloudfront/OAI-ID" }, "ConnectionAttempts": 3, "ConnectionTimeout": 10, "OriginShield": { "Enabled": false }, "OriginAccessControlId": "" } ] }, "OriginGroups": { "Quantity": 0 }, "DefaultCacheBehavior": { "TargetOriginId": "problem.example.com.s3.us-east-1.amazonaws.com", "TrustedSigners": { "Enabled": false, "Quantity": 0 }, "TrustedKeyGroups": { "Enabled": false, "Quantity": 0 }, "ViewerProtocolPolicy": "https-only", "AllowedMethods": { "Quantity": 3, "Items": [ "HEAD", "GET", "OPTIONS" ], "CachedMethods": { "Quantity": 3, "Items": [ "HEAD", "GET", "OPTIONS" ] } }, "SmoothStreaming": false, "Compress": true, "LambdaFunctionAssociations": { "Quantity": 1, "Items": [ { "LambdaFunctionARN": "arn:aws:lambda:us-east-1:SOME-NUMBER:function:myFunctionName:7", "EventType": "viewer-request", "IncludeBody": false } ] }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "ForwardedValues": { "QueryString": false, "Cookies": { "Forward": "none" }, "Headers": { "Quantity": 1, "Items": [ "Authorization" ] }, "QueryStringCacheKeys": { "Quantity": 0 } }, "MinTTL": 0, "DefaultTTL": 60, "MaxTTL": 600 }, "CacheBehaviors": { "Quantity": 0 }, "CustomErrorResponses": { "Quantity": 0 }, "Comment": "", "Logging": { "Enabled": true, "IncludeCookies": false, "Bucket": "logging.example.com.s3.amazonaws.com", "Prefix": "problem" }, "PriceClass": "PriceClass_100", "Enabled": true, "ViewerCertificate": { "CloudFrontDefaultCertificate": false, "ACMCertificateArn": "CERTIFICATE-ARN", "SSLSupportMethod": "sni-only", "MinimumProtocolVersion": "TLSv1.2_2021", "Certificate": "CERTIFICATE-ARN", "CertificateSource": "acm" }, "Restrictions": { "GeoRestriction": { "RestrictionType": "none", "Quantity": 0 } }, "WebACLId": "", "HttpVersion": "http2", "IsIPV6Enabled": true, "ContinuousDeploymentPolicyId": "", "Staging": false } }
解决方法
- 确认CloudFront配置已生效:修改CloudFront缓存行为的头转发配置后,需要等待分发完成部署(状态变为
Deployed),这个过程通常需要15-20分钟。如果修改后立即测试,配置可能还未生效,导致Authorization头未被转发。 - 注意请求头的大小写转换:CloudFront会将所有请求头转换为小写形式,因此在Lambda函数中需要通过
headers['authorization'](全小写)来获取,而不是headers.Authorization。这是最可能导致你看不到头的原因,修改后的示例代码如下:export const handler = async (event, context) => { const request = event.Records[0].cf.request; const headers = request.headers; // 用小写键获取Authorization头 const authHeader = headers['authorization']; let responseBody = 'Unauthorized!\n'; if (authHeader) { responseBody += `Authorization header detected: ${JSON.stringify(authHeader)}`; } else { responseBody += 'Authorization header not found.\n'; responseBody += `All available headers: ${JSON.stringify(headers)}`; } return { status: '401', statusDescription: 'Unauthorized', body: responseBody, headers: { 'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}] }, }; }; - 验证浏览器实际发送的请求头:使用浏览器开发者工具的Network面板,确认请求的Request Headers中确实包含Authorization字段。部分场景下(如跨域请求),浏览器可能需要额外的CORS配置才会发送认证头。
- 排查Lambda执行角色权限:确保Lambda@Edge的执行角色信任关系包含
edgelambda.amazonaws.com,并且具备必要的Lambda执行权限。不过此问题中权限问题的可能性较低,但可作为兜底排查项。
内容的提问来源于stack exchange,提问作者Guido Flohr
相关产品推荐
相关产品推荐

