CloudFront 与 Lambda@Edge 导致 CORS 问题
CloudFront with Lambda@Edge results in CORS problem
我已将 S3 配置为只能通过 CloudFront 进行访问,并使用根据查看者请求执行的 lambda 进行保护。问题是由于预检调用失败,我无法从 SPA 访问文件。
当我删除 lambda 函数时,一切都开始工作了。这让我感到惊讶,因为 lambda 根本没有修改请求。
这是我的配置:
S3:
CloudFront:
Lambda@Edge(应查看者请求执行)
exports.handler = async (event, context, callback) => {
let request;
let token;
try {
request = event.Records[0].cf.request;
const headers = request.headers;
const authorization = headers['authorization'][0];
const authorizationValue = authorization.value;
token = authorizationValue.substring(7);
} catch (error) {
console.error("Missing authorization header", error);
callback(null, missingAuthorizationHeaderResponse);
}
if (token) {
try {
if (!secret) {
secret = await getSecret();
}
jwt.verify(token, secret);
console.log("Token valid");
callback(null, request);
} catch (error) {
console.error("Token not valid", error);
callback(null, invalidTokenResponse);
}
} else {
console.error("Token not found");
callback(null, missingAuthorizationHeaderResponse);
}
};
非常感谢您的帮助,因为我在这个案例上花了很多时间,谢谢!
问题是预检调用是在没有任何额外 header 的情况下执行的,在我的例子中,“授权”header 丢失并生成 403。我通过查看日志发现拉姆达。我已经添加了对 lambda 的选项调用的处理。此外,我还必须更改 s3 配置以使响应具有可见的 CORS headers.
Lambda 代码:
const preflightCall = {
status: "204",
headers: {
'access-control-allow-origin': [{
key: 'Access-Control-Allow-Origin',
value: "*",
}],
'access-control-request-method': [{
key: 'Access-Control-Request-Method',
value: "PUT, GET, OPTIONS, DELETE",
}],
'access-control-allow-headers': [{
key: 'Access-Control-Allow-Headers',
value: "*",
}]
},
};
exports.handler = async (event, context, callback) => {
let request;
let token;
try {
request = event.Records[0].cf.request;
if(request.method === 'OPTIONS') {
console.log('preflight call');
callback(null, preflightCall);
return;
}
const headers = request.headers;
const authorization = headers['authorization'][0];
const authorizationValue = authorization.value;
token = authorizationValue.substring(7);
} catch (error) {
console.error("Missing authorization header", error);
callback(null, missingAuthorizationHeaderResponse);
}
if (token) {
try {
if (!secret) {
secret = await getSecret();
}
jwt.verify(token, secret);
console.log("Token valid");
callback(null, request);
} catch (error) {
console.error("Token not valid", error);
callback(null, invalidTokenResponse);
}
} else {
console.error("Token not found");
callback(null, missingAuthorizationHeaderResponse);
}
};
S3:
[
{
"AllowedHeaders": [
"Authorization"
],
"AllowedMethods": [
"GET",
"HEAD",
"DELETE",
"POST",
"PUT"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"Access-Control-Allow-Origin"
],
"MaxAgeSeconds": 3000
}
]
我已将 S3 配置为只能通过 CloudFront 进行访问,并使用根据查看者请求执行的 lambda 进行保护。问题是由于预检调用失败,我无法从 SPA 访问文件。
当我删除 lambda 函数时,一切都开始工作了。这让我感到惊讶,因为 lambda 根本没有修改请求。
这是我的配置:
S3:
CloudFront:
Lambda@Edge(应查看者请求执行)
exports.handler = async (event, context, callback) => {
let request;
let token;
try {
request = event.Records[0].cf.request;
const headers = request.headers;
const authorization = headers['authorization'][0];
const authorizationValue = authorization.value;
token = authorizationValue.substring(7);
} catch (error) {
console.error("Missing authorization header", error);
callback(null, missingAuthorizationHeaderResponse);
}
if (token) {
try {
if (!secret) {
secret = await getSecret();
}
jwt.verify(token, secret);
console.log("Token valid");
callback(null, request);
} catch (error) {
console.error("Token not valid", error);
callback(null, invalidTokenResponse);
}
} else {
console.error("Token not found");
callback(null, missingAuthorizationHeaderResponse);
}
};
非常感谢您的帮助,因为我在这个案例上花了很多时间,谢谢!
问题是预检调用是在没有任何额外 header 的情况下执行的,在我的例子中,“授权”header 丢失并生成 403。我通过查看日志发现拉姆达。我已经添加了对 lambda 的选项调用的处理。此外,我还必须更改 s3 配置以使响应具有可见的 CORS headers.
Lambda 代码:
const preflightCall = {
status: "204",
headers: {
'access-control-allow-origin': [{
key: 'Access-Control-Allow-Origin',
value: "*",
}],
'access-control-request-method': [{
key: 'Access-Control-Request-Method',
value: "PUT, GET, OPTIONS, DELETE",
}],
'access-control-allow-headers': [{
key: 'Access-Control-Allow-Headers',
value: "*",
}]
},
};
exports.handler = async (event, context, callback) => {
let request;
let token;
try {
request = event.Records[0].cf.request;
if(request.method === 'OPTIONS') {
console.log('preflight call');
callback(null, preflightCall);
return;
}
const headers = request.headers;
const authorization = headers['authorization'][0];
const authorizationValue = authorization.value;
token = authorizationValue.substring(7);
} catch (error) {
console.error("Missing authorization header", error);
callback(null, missingAuthorizationHeaderResponse);
}
if (token) {
try {
if (!secret) {
secret = await getSecret();
}
jwt.verify(token, secret);
console.log("Token valid");
callback(null, request);
} catch (error) {
console.error("Token not valid", error);
callback(null, invalidTokenResponse);
}
} else {
console.error("Token not found");
callback(null, missingAuthorizationHeaderResponse);
}
};
S3:
[
{
"AllowedHeaders": [
"Authorization"
],
"AllowedMethods": [
"GET",
"HEAD",
"DELETE",
"POST",
"PUT"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"Access-Control-Allow-Origin"
],
"MaxAgeSeconds": 3000
}
]