2

我正在开发一个使用 React 和 AWS S3 提供视频点播服务的网站。
我需要必须授权才能观看视频。
所以我考虑在请求时使用签名cookie。

使用 curl 请求成功。

curl -H 'Cookie:CloudFront-Policy=eyJTd*******************;CloudFront-Signature=b8wt************************************; CloudFront-Key-Pair-Id=AP**********' http://*********.cloudfront.net/hogehoge.m3u8

但我无法在 React 获得文件。
我的代码在那里。

export function Movie(){
    document.cookie = `CloudFront-Key-Pair-Id=${"AP**************"}; `
    document.cookie = `CloudFront-Policy=${"eyJT*****************"}; `
    document.cookie = `CloudFront-Signature=${"b8wt****************"}; `

    <ReactPlayer
        url={"http://******.cloudfront.net/hogehoge.m3u8"}
        controls
        config={{
            file: {
                hlsOptions: { 
                xhrSetup: function(xhr: any, url: any) {
                    xhr.withCredentials = true // send cookies
                }
                }
            }
        }}
    >
}

Chrome 上的错误消息(图片

Request URL: http://*****.cloudfront.net/hogehoge.m3u8
Referrer Policy: strict-origin-when-cross-origin
Connection: keep-alive
Content-Length: 146
Content-Type: text/xml
Date: Tue, 27 Oct 2020 05:54:03 GMT
Server: CloudFront
Via: 1.1 *********.cloudfront.net (CloudFront)
X-Amz-Cf-Id: *******
X-Amz-Cf-Pop: NRT12-C3
X-Cache: Error from cloudfront
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: ja-JP,ja;q=0.9,en-JP;q=0.8,en;q=0.7,en-US;q=0.6
Connection: keep-alive
DNT: 1
Host: ********.cloudfront.net
Origin: http://localhost:3000
Referer: http://localhost:3000/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36

该请求看起来不包括 cookie。
我该如何解决这个问题?

4

1 回答 1

0

显然,问题之一是 CORS 策略的执行。如果您查看响应,您可以看到主机/引荐来源(即 localhost:3000)与目标不同(OP 已编辑但我们假设它是 blah.cloudfront.net)。即使解决了 CORS,您也需要确保正确设置 Cloudfront 和 S3。我正在列出对我有用的东西:

  1. 将自定义域分配给云端,以便自定义域是您的应用程序前端运行的子域。在 OP 的情况下,他使用的是 localhost:3000;很可能他正在测试他的开发设置,但他必须在某个域部署这个应用程序:让我们称之为“myapp.com”。因此,他可以分配一个自定义域,例如 cdn.myapp.com 以指向 blah.cloudfront.net。您需要为新的自定义域创建/导入自定义 SSL 证书;默认的云端证书不起作用。在此处输入图像描述请参考:https ://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html[![在此处输入图像描述] 2 ] 2第一个没有自定义域,因此是一个空的 CNAME 列。第二个是有一个自定义域,因此我们在那里打印了一个。您可以通过这种方式验证您的自定义域是否已指向云端分发。
  2. Cloudfront 行为:我假设您已经设置了受信任的密钥组,因为此时您已经拥有签名的 cookie。但是,您将需要创建自定义缓存策略和源请求策略。在此处输入图像描述请参阅以下自定义缓存策略的屏幕截图:在此处输入图像描述和 Origin Request Policy:在此处输入图像描述需要注意的是,您需要将这些标头列入白名单:Origin、Access-Control-Request-Method、Access-Control-Allow-Origin、Access-Control -请求标头。(您可能会注意到 Access-Control-Allow-Origin 不在下拉列表中;只需继续输入它!)。此外,允许所有 cookie。
  3. S3 CORS 配置:转到 S3 存储桶并单击权限选项卡。向下滚动到 CORS 配置。免责声明:我只是粘贴了对我有用的内容。这背后的基本原理是,在我的场景中,这个 S3 将由 CDN 或应用程序访问。我尝试将“*”放宽,但 Chrome 上的 CORS 政策抱怨我不能在 AllowedOrigins 中使用通配符条目!
[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "PUT",
            "POST",
            "GET",
            "HEAD",
            "DELETE"
        ],
        "AllowedOrigins": [
            "cdn.myapp.com",
            "myapp.com",
            "https://cdn.myapp.com",
            "https://myapp.com"
        ],
        "ExposeHeaders": [
            "ETag"
        ]
    }
]
  1. react-player:我正在使用这样的 react-player(注意设置了 forceHLS 选项,但它又是针对我的用例的。我认为这通常不是强制性的)
<ReactPlayer
    className="react-player"
    url={url}
    controls={controls}
    light={light}
    config={
      {
        file: {
          forceHLS: true,
          hlsOptions: {
            xhrSetup: function (xhr, url) {
              xhr.withCredentials = true; // send cookies
            },
          },
        },
      }
    }
    playIcon={<PlayIcon />}
    width="100%"
    height="100%"
  />
于 2021-06-10T22:34:24.763 回答