无法使用 AWS CloudFront 签名 Cookie 播放 HLS m3u8 文件

问题描述

我正在处理一个需要播放 HLS 加密视频 (.m3u8) 文件的项目。我正在使用 CloudFront 和签名 cookie 来保护内容。我可以在没有签名 cookie 的情况下播放 .m3u8 文件,但是当我使用签名 cookie 时,cookie 不会发送请求。

我正在使用 CloudFront 分配的备用域,并且我确认除了 .m3u8 文件之外,我可以使用签名的 cookie 访问所有其他文件。

经过研究,我发现如果我像下面的代码那样将 withCredentials 设置为 true,那么签名的 cookie 将在请求中发送:

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 分发行为的屏幕截图:

enter image description here

enter image description here

enter image description here

这是我的 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',withCredentials: true
        });
    });
</script>

</body>
</html>

这是 S3 反抗 CORS 政策:

[
    {
        "AllowedHeaders": [
            ""
        ],"AllowedMethods": [
            "POST","GET","PUT","HEAD"
        ],"AllowedOrigins": [
            "*"
        ],"ExposeHeaders": []
    }
]

提前致谢。

解决方法

答案在浏览器的错误消息中,“当请求的凭据模式为‘包含’时,响应中‘Access-Control-Allow-Origin’标头的值不能是通配符‘*’。”您的 S3 存储桶的 CORS 策略不能对 AllowedOrigins 值使用通配符。

此外,您的空 AllowedHeaders 值可能会从预检请求检查中删除 Host 值,因此为了安全起见,让我们将其设置为通配符。

如果您将 S3 存储桶的 CORS 策略更新为此,它应该可以解决问题:

[
    {
        "AllowedHeaders": [
            "*"
        ],"AllowedMethods": [
            "POST","GET","PUT","HEAD"
        ],"AllowedOrigins": [
            "https://example.com","https://protected.example.com"
        ],"ExposeHeaders": []
    }
]

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...