You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS中使用CloudFront签名Cookie无法播放视频内容的问题

问题排查:NextJS播放器加载CloudFront私有视频时的CORS错误

概述

我正在搭建一个基于用户权限展示私有视频的网站:前端采用NextJS(运行在http://localhost:3000),后端采用NestJS(运行在http://localhost:5000),视频存储在私有S3桶中,用户授权后通过CloudFront生成的签名Cookie访问视频内容。

问题

当浏览器已正确存储CloudFront-Key-Pair-Id、CloudFront-Policy、CloudFront-Signature三个Cookie时,直接访问视频地址https://xxxxxx.cloudfront.net/video/intro.mp4可正常播放,但在NextJS应用的播放器中尝试加载时,视频无法播放,返回错误:

'http://localhost:3000' 已被CORS策略阻止:请求的资源上不存在 'Access-Control-Allow-Origin' 标头。

环境配置

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"
                }
            }
        }
    ]
}

CloudFront

  • 源请求策略
    源请求策略

NestJS后端

  • 主文件CORS配置
app.enableCors({
    origin: 'http://localhost:3000',
    credentials: true,
});
  • 控制器设置Cookie代码
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,
});

解决方案

1. 修正CloudFront的CORS配置

CloudFront作为请求入口,需允许http://localhost:3000的跨域请求:

  • 进入CloudFront控制台,找到对应分发,切换到行为标签
  • 编辑目标行为,在缓存策略和源请求策略部分,确保关联包含Origin请求头的源请求策略
  • 在行为的**跨域资源共享(CORS)**设置中,添加允许源http://localhost:3000,并启用CORS选项

2. 更新S3存储桶的CORS策略

将AllowedOrigins添加http://localhost:3000,修改后策略如下:

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET"
        ],
        "AllowedOrigins": [
            "https://xxxxxxx.cloudfront.net",
            "http://localhost:3000"
        ],
        "ExposeHeaders": [
            "ETag",
            "Access-Control-Allow-Origin"
        ]
    }
]

3. 修正Cookie的域名配置

当前NestJS设置Cookie的domain为localhost,但这些Cookie需要发送到CloudFront域名才能生效,修改控制器中的Cookie配置:

response.cookie(
    'CloudFront-Key-Pair-Id',
    cookies['CloudFront-Key-Pair-Id'],
    {
        domain: '.xxxxxx.cloudfront.net', // 前缀点适配子域名
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production', // 生产环境开启,localhost测试可关闭
        sameSite: 'none', // 跨域请求需设置为none
    },
);
// CloudFront-Policy、CloudFront-Signature两个Cookie做同样修改

4. 确保播放器请求携带Cookie

在NextJS播放器组件中,确保请求CloudFront视频地址时携带凭证。比如使用原生<video>标签时添加属性:

<video
    src="https://xxxxxx.cloudfront.net/video/intro.mp4"
    crossOrigin="use-credentials"
    controls
/>

若使用第三方播放器库,需配置对应跨域携带凭证选项。


内容的提问来源于stack exchange,提问作者user16257618

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 08:30:16