Cloudfront 在重定向时抛出 403
Cloudfront throw 403 on redirect
我有一个 Lambda Edge 附加到应该处理重定向的 Origin Request 事件。代码非常简单,它检查请求的 URL 是否在 DynamoDB Table 中,如果是,它 returns 一个带有重定向 URL 的 301 响应。
这是我拥有的 Lambda Edge 代码
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 Edge 函数在 eu-central-1 上运行,这是离我所在位置最近的边缘,但 DynamoDB table 在 us-east-1 中。所以我将我的代码更改为此并且一切正常:)
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;
}
我有一个 Lambda Edge 附加到应该处理重定向的 Origin Request 事件。代码非常简单,它检查请求的 URL 是否在 DynamoDB Table 中,如果是,它 returns 一个带有重定向 URL 的 301 响应。 这是我拥有的 Lambda Edge 代码
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 Edge 函数在 eu-central-1 上运行,这是离我所在位置最近的边缘,但 DynamoDB table 在 us-east-1 中。所以我将我的代码更改为此并且一切正常:)
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;
}