无法使用 AWS CloudFront 签名的 Cookie 播放 HLS m3u8 文件
Unable to play HLS m3u8 file with AWS CloudFront Signed Cookies
我正在做一个需要播放 HLS 加密视频 (.m3u8) 文件的项目。我正在使用 CloudFront 和签名的 cookie 来保护内容。我可以在没有签名 cookie 的情况下播放 .m3u8 文件,但是当我使用签名 cookie 时,cookie 不会在请求中发送。
我正在使用备用域进行 CloudFront 分发,我确认除了 .m3u8 文件外,我可以使用签名 cookie 访问所有其他文件。
经过研究,我发现如果我像下面的代码一样将withCredentials
设置为true,那么签名的cookies将在请求中发送:
player.ready(function() {
player.src({
src: 'https://protected.example.com/output-plain/art.m3u8',
type: 'application/x-mpegURL',
withCredentials: true
});
});
此代码有效,签名的 cookie 正在请求中发送,但是我开始收到一个新错误:
Access to XMLHttpRequest at 'https://protected.example.com/output-plain/art.m3u8undefined' from origin 'https://example.com' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
然后我发现我必须将Access-Control-Allow-Credentials
设置为true。但是,这对我不起作用。
我正在使用 video.js 库,我也尝试过 hls.js 并遇到同样的错误并卡在同一个地方。
在过去的 7 天里,我一直被这个问题困扰,我认为 AWS 文档真的让人不知所措,我已经提到了很多关于 SO 的问题和关于 Github 的问题,但仍然没有成功。希望有人能在这里帮助我。
以下是 CloudFront 分发行为的屏幕截图:
这是我的 php 和 js 代码; index.php:
<?php
header("Access-Control-Allow-Origin: https://protected.example.com");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Max-Age: 1000");
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Cache-Control, Pragma, Authorization, Accept, Accept-Encoding");
header("Access-Control-Allow-Methods: PUT, POST, GET, OPTIONS, DELETE");
?>
<!DOCTYPE html>
<html>
<head>
<link href="https://vjs.zencdn.net/7.10.2/video-js.css" rel="stylesheet" />
</head>
<body>
<video
id="video_player"
class="video-js"
controls
preload="auto"
poster="//vjs.zencdn.net/v/oceans.png"
data-setup='{}'
width=600 height=300>
</video>
<script src="https://vjs.zencdn.net/7.10.2/video.js"></script>
<script>
var player = videojs('video_player')
player.responsive(true);
player.ready(function() {
player.src({
src: 'https://protected.example.com/output-plain/art.m3u8',
type: 'application/x-mpegURL',
withCredentials: true
});
});
</script>
</body>
</html>
这是 S3 bucked CORS 策略:
[
{
"AllowedHeaders": [
""
],
"AllowedMethods": [
"POST",
"GET",
"PUT",
"HEAD"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": []
}
]
提前致谢。
答案在浏览器的错误消息中,“当请求的凭据模式为[=20=时,响应中'Access-Control-Allow-Origin' header的值不能是通配符'*' ]."您的 S3 存储桶的 CORS 策略不能对 AllowedOrigins 值使用通配符。
另外,您的空 AllowedHeaders 值 可能 会从预检请求检查中删除主机值,因此为了安全起见,我们将其设置为通配符。
如果您将 S3 存储桶的 CORS 策略更新为此,应该可以解决问题:
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"POST",
"GET",
"PUT",
"HEAD"
],
"AllowedOrigins": [
"https://example.com",
"https://protected.example.com"
],
"ExposeHeaders": []
}
]
我正在做一个需要播放 HLS 加密视频 (.m3u8) 文件的项目。我正在使用 CloudFront 和签名的 cookie 来保护内容。我可以在没有签名 cookie 的情况下播放 .m3u8 文件,但是当我使用签名 cookie 时,cookie 不会在请求中发送。
我正在使用备用域进行 CloudFront 分发,我确认除了 .m3u8 文件外,我可以使用签名 cookie 访问所有其他文件。
经过研究,我发现如果我像下面的代码一样将withCredentials
设置为true,那么签名的cookies将在请求中发送:
player.ready(function() {
player.src({
src: 'https://protected.example.com/output-plain/art.m3u8',
type: 'application/x-mpegURL',
withCredentials: true
});
});
此代码有效,签名的 cookie 正在请求中发送,但是我开始收到一个新错误:
Access to XMLHttpRequest at 'https://protected.example.com/output-plain/art.m3u8undefined' from origin 'https://example.com' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
然后我发现我必须将Access-Control-Allow-Credentials
设置为true。但是,这对我不起作用。
我正在使用 video.js 库,我也尝试过 hls.js 并遇到同样的错误并卡在同一个地方。
在过去的 7 天里,我一直被这个问题困扰,我认为 AWS 文档真的让人不知所措,我已经提到了很多关于 SO 的问题和关于 Github 的问题,但仍然没有成功。希望有人能在这里帮助我。
以下是 CloudFront 分发行为的屏幕截图:
这是我的 php 和 js 代码; index.php:
<?php
header("Access-Control-Allow-Origin: https://protected.example.com");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Max-Age: 1000");
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Cache-Control, Pragma, Authorization, Accept, Accept-Encoding");
header("Access-Control-Allow-Methods: PUT, POST, GET, OPTIONS, DELETE");
?>
<!DOCTYPE html>
<html>
<head>
<link href="https://vjs.zencdn.net/7.10.2/video-js.css" rel="stylesheet" />
</head>
<body>
<video
id="video_player"
class="video-js"
controls
preload="auto"
poster="//vjs.zencdn.net/v/oceans.png"
data-setup='{}'
width=600 height=300>
</video>
<script src="https://vjs.zencdn.net/7.10.2/video.js"></script>
<script>
var player = videojs('video_player')
player.responsive(true);
player.ready(function() {
player.src({
src: 'https://protected.example.com/output-plain/art.m3u8',
type: 'application/x-mpegURL',
withCredentials: true
});
});
</script>
</body>
</html>
这是 S3 bucked CORS 策略:
[
{
"AllowedHeaders": [
""
],
"AllowedMethods": [
"POST",
"GET",
"PUT",
"HEAD"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": []
}
]
提前致谢。
答案在浏览器的错误消息中,“当请求的凭据模式为[=20=时,响应中'Access-Control-Allow-Origin' header的值不能是通配符'*' ]."您的 S3 存储桶的 CORS 策略不能对 AllowedOrigins 值使用通配符。
另外,您的空 AllowedHeaders 值 可能 会从预检请求检查中删除主机值,因此为了安全起见,我们将其设置为通配符。
如果您将 S3 存储桶的 CORS 策略更新为此,应该可以解决问题:
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"POST",
"GET",
"PUT",
"HEAD"
],
"AllowedOrigins": [
"https://example.com",
"https://protected.example.com"
],
"ExposeHeaders": []
}
]