总结
目前我正在尝试建立一个根据用户权限显示私人视频的网站。我使用 NextJS (http://localhost:3000) 托管前端,使用 NestJS (http://localhost:5000) 托管后端。我将视频存储在私有 S3 存储桶中,并使用 CloudFront 生成签名 cookie(如果用户已授权)并显示内容。
问题
如果我直接访问视频
https://xxxxxx.cloudfront.net/video/intro.mp4
,并且cookie:CloudFront-Key-Pair-Id
、CloudFront-Policy
、CloudFront-Signature
正确存储在浏览器页面中,我可以很好地观看视频。但是,如果我尝试在 (http://localhost:3000)
中的 NextJS 应用程序的视频播放器中播放此视频,则视频不会播放并返回 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
。
设置
S3 铲斗
CORS 政策
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET"
],
"AllowedOrigins": [
"https://xxxxxxx.cloudfront.net"
],
"ExposeHeaders": [
"ETag",
"Access-Control-Allow-Origin"
]
}
]
桶政策
{
"Version": "2008-10-17",
"Id": "PolicyForPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::xxxxx-private/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::xxxxxx"
}
}
}
]
}
云前
原产地请求政策
NestJS
主要
app.enableCors({
origin: 'http://localhost:3000',
credentials: true,
});
控制器
async access() {
const cookies = await this.service.getAccess(id);
response.cookie(
'CloudFront-Key-Pair-Id',
cookies['CloudFront-Key-Pair-Id'],
{
domain: 'localhost',
httpOnly: true,
},
);
response.cookie('CloudFront-Policy', cookies['CloudFront-Policy'], {
domain: 'localhost',
httpOnly: true,
});
response.cookie(
'CloudFront-Signature',
cookies['CloudFront-Signature'],
{
domain: 'localhost',
httpOnly: true,
},
);
return 'Success';
}
NextJS
API调用
const response = await axios.get(`${this.client}/${url}`, {
headers: {
...headers,
Authorization: `Bearer ${getCookie("Access-Token")}`,
},
withCredentials: true,
});
错误
'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
这似乎不是 Cloudfront 或您的存储桶策略的问题。因为当您直接从浏览器加载时它效果很好。我认为这可能是由于您的
next.config.js
配置所致。您的 remotePatterns
数组中目前有什么?如果您尚未添加 cloudfront
主机名,CORS 错误将持续存在。请执行此操作,您应该能够访问您的视频资源
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'xxxxxx.cloudfront.net', // Your CloudFront domain
pathname: '/video/*', // The path pattern for the video
},
],
},
};