集成Lambda授权器的API Gateway执行Allow策略时返回内部服务器错误
问题描述
- 使用CloudFormation部署Lambda授权器,调用API Gateway端点时出现异常:
- 当Authorization头值为"deny"时,返回正确的403响应
- 当Authorization头值为"allow"时,返回"Internal Server Error"
- Lambda授权器代码参考AWS官方文档,模板中的Lambda部分代码如下:
AuthorizerForAPIGW: Type: AWS::Serverless::Function Properties: FunctionName: "authorizer-for-api-gw" Role: !GetAtt LambdaFuncRoleForAuthorizer.Arn Handler: src/index.handler Runtime: nodejs16.x MemorySize: 320 Timeout: 20 InlineCode: | exports.handler = function(event, context, callback) { var token = event.authorizationToken; switch (token) { case 'allow': callback(null, generatePolicy('user', 'Allow', event.methodArn)); break; case 'deny': callback(null, generatePolicy('user', 'Deny', event.methodArn)); break; case 'unauthorized': callback("Unauthorized"); // Return a 401 Unauthorized response break; default: callback("Error: Invalid token"); // Return a 500 Invalid token response } }; var generatePolicy = function(principalId, effect, resource) { var authResponse = {}; authResponse.principalId = principalId; if (effect && resource) { var policyDocument = {}; policyDocument.Version = '2012-10-17'; policyDocument.Statement = []; var statementOne = {}; statementOne.Action = 'execute-api:Invoke'; statementOne.Effect = effect; statementOne.Resource = resource; policyDocument.Statement[0] = statementOne; authResponse.policyDocument = policyDocument; console.log("statement",statementOne); console.log("policyDocument",policyDocument); } authResponse.context = { "stringKey": "stringval", "numberKey": 123, "booleanKey": true }; return authResponse; }
问题原因
Lambda代码中authResponse.context对象的键值对被错误地使用了HTML转义字符",这会导致JavaScript语法错误,使得Lambda函数执行失败,API Gateway因此返回500内部错误。
注:传入"deny"时看似正常,实际是API Gateway处理Deny策略时的容错逻辑,本质上代码存在语法问题。
解决方案
- 修正Lambda代码中的转义字符:将InlineCode里所有的
"替换为普通双引号",确保JavaScript语法合法。修正后的InlineCode部分如下:
InlineCode: | exports.handler = function(event, context, callback) { var token = event.authorizationToken; switch (token) { case 'allow': callback(null, generatePolicy('user', 'Allow', event.methodArn)); break; case 'deny': callback(null, generatePolicy('user', 'Deny', event.methodArn)); break; case 'unauthorized': callback("Unauthorized"); // Return a 401 Unauthorized response break; default: callback("Error: Invalid token"); // Return a 500 Invalid token response } }; var generatePolicy = function(principalId, effect, resource) { var authResponse = {}; authResponse.principalId = principalId; if (effect && resource) { var policyDocument = {}; policyDocument.Version = '2012-10-17'; policyDocument.Statement = []; var statementOne = {}; statementOne.Action = 'execute-api:Invoke'; statementOne.Effect = effect; statementOne.Resource = resource; policyDocument.Statement[0] = statementOne; authResponse.policyDocument = policyDocument; console.log("statement",statementOne); console.log("policyDocument",policyDocument); } authResponse.context = { "stringKey": "stringval", "numberKey": 123, "booleanKey": true }; return authResponse; }
- 验证Lambda执行日志:部署修正后的模板后,通过CloudWatch Logs查看Lambda授权器的执行日志,确认无语法错误或其他异常。
- 重新测试API端点:在Postman中再次调用API,分别传入"allow"和"deny"的Authorization头,验证响应是否符合预期:
- "allow":返回后端服务的正常响应(或200状态码)
- "deny":返回403 Forbidden响应
内容的提问来源于stack exchange,提问作者Devashish Priyadarshi
相关产品推荐
相关产品推荐

