Amazon web services Cloudfront在重定向时抛出403
我有一个Lambda边缘连接到应该处理重定向的originrequest事件。代码非常简单,它检查请求的URL是否在DynamoDB表中,如果在DynamoDB表中,则返回带有重定向URL的301响应。 这是我的Lambda边缘代码Amazon web services Cloudfront在重定向时抛出403,amazon-web-services,redirect,amazon-dynamodb,amazon-cloudfront,aws-lambda-edge,Amazon Web Services,Redirect,Amazon Dynamodb,Amazon Cloudfront,Aws Lambda Edge,我有一个Lambda边缘连接到应该处理重定向的originrequest事件。代码非常简单,它检查请求的URL是否在DynamoDB表中,如果在DynamoDB表中,则返回带有重定向URL的301响应。 这是我的Lambda边缘代码 const aws = require("aws-sdk"); const dynamoDB = new aws.DynamoDB.DocumentClient(); exports.handler = async (event, context, callback
const aws = require("aws-sdk");
const dynamoDB = new aws.DynamoDB.DocumentClient();
exports.handler = async (event, context, callback) => {
const request = event.Records[0].cf.request;
const uri = request.uri;
let redirect = await getRedirect(uri);
if (redirect) {
const redirectResponse = createRedirect(redirect.To);
callback(null, redirectResponse);
return;
}
callback(null, request);
return request;
};
function getRedirect(uri) {
let params = {
TableName: "Redirects",
KeyConditionExpression: "#from = :from",
ExpressionAttributeNames: {
"#from": "From"
},
ExpressionAttributeValues: {
":from": uri
}
};
return dynamoDB
.query(params)
.promise()
.then(result => result.Items[0])
.catch(reject => null);
}
function createRedirect(uri) {
const response = {
status: "302",
statusDescription: "Found",
headers: {
"cache-control": [
{
key: "Cache-Control",
value: "max-age=0"
}
],
location: [
{
key: "Location",
value: uri
}
]
}
};
return response;
}
如果我使用测试事件测试Lambda函数,就会得到重定向响应。然而,当我尝试使用CloudFront获取重定向时,我得到一个403错误。因此,假设URL
/a
应该重定向到/b
。如果我调用cloudfront.url/a
,我会收到一条消息,告诉我对象已经被移动到/b
(或者更好的是被自动重定向)。相反,我得到了403错误。Lambda是否有问题,或者我需要向CloudFront附加一些权限才能使重定向正常工作?感谢Niobos的帮助,我找到了问题所在。问题出在DynamoDB地区。我的Lambda边函数在eu-central-1上运行,这是离我所在位置最近的边,但DynamoDB表在us-east-1中。所以我把代码改成了这个,一切都正常了:)
您能否提供应该导致重定向的HTTP请求的更详细输出(例如通过运行
curl cloudfront.url/a
)?你确定Lambda@Edge是否有效触发(例如,通过验证CloudWatch日志)?如果我对必须重定向的URL进行卷曲,我会得到以下AccessDenied
accessdenied54c54423d45b705di/9weyfzv8fg3rsbg2jfnqdha11vbv8rluyfgkumtdnb8iv3vbcg6q7jk2s9fo2ckgklvlmrpu=
是,Lambda被命中,因为我可以看到使用正确的时间戳创建请求日志。在这种情况下,您的Lambda@Edge函数未返回重定向(curl URL
不会自动跟随重定向)。您可以在getRedirect()
函数中添加一些调试语句来找出原因console.log()
将在CloudWatch日志中结束。有趣的是:在CloudWatch上,它说Lambda角色没有权限在DynamoDB上执行查询。但是,角色具有查询权限,而且正如我所说的,如果使用测试事件,它将执行查询。只有在CloudFront中,它才会以某种方式释放权限。编辑:我给了Lambda角色对DynamoDB的所有权限,但它没有改变。你能验证你是否进入了正确的区域吗?Lambda@Edge在CloudFront服务器的区域中运行,该区域不一定是DynamoDB表所在的区域。最好在中显式指定区域Lambda@Edge代码。
const aws = require("aws-sdk");
const dynamoDB = new aws.DynamoDB.DocumentClient({ region: "us-east-1" });
exports.handler = async (event, context, callback) => {
const request = event.Records[0].cf.request;
const uri = request.uri;
let redirect = await getRedirect(uri);
if (redirect) {
const redirectResponse = createRedirect(redirect.To);
callback(null, redirectResponse);
return;
}
callback(null, request);
return request;
};
function getRedirect(uri) {
let params = {
TableName: "Redirects",
KeyConditionExpression: "#from = :from",
ExpressionAttributeNames: {
"#from": "From"
},
ExpressionAttributeValues: {
":from": uri
}
};
return dynamoDB
.query(params)
.promise()
.then(result => result.Items[0])
.catch(reject => null);
}
function createRedirect(uri) {
const response = {
status: "302",
statusDescription: "Found",
headers: {
"cache-control": [
{
key: "Cache-Control",
value: "max-age=0"
}
],
location: [
{
key: "Location",
value: uri
}
]
}
};
return response;
}