如何使用来自 AWS S3 的预签名 cookie 在 ReactPlayer 上实现电影播放器 [英] How can I implement a movie player on ReactPlayer with presigned cookies from AWS S3

查看:59
本文介绍了如何使用来自 AWS S3 的预签名 cookie 在 ReactPlayer 上实现电影播放器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个使用 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 中获取文件.
我的代码在那里.

导出函数 Movie(){document.cookie = `CloudFront-Key-Pair-Id=${AP**************"};`document.cookie = `CloudFront-Policy=${"eyJT********************"};`document.cookie = `CloudFront-Signature=${b8wt****************"};`<反应播放器url={http://******.cloudfront.net/hogehoge.m3u8"}控制配置={{文件: {hls选项:{xhrSetup:函数(xhr:任何,网址:任何){xhr.withCredentials = true//发送 cookie}}}}}>}

Chrome 上的错误消息( 参考: 自定义缓存策略的截图如下:和来源请求政策: 需要注意的是,您需要将这些标头列入白名单:Origin、Access-Control-Request-Method、Access-Control-Allow-Origin、Access-Control-Request-Headers.(您可能会注意到 Access-Control-Allow-Origin 不在下拉列表中;直接输入即可!).此外,允许所有 cookie.

  • S3 CORS 配置:转到 S3 存储桶并单击权限选项卡.向下滚动到 CORS 配置.免责声明:我只是粘贴了对我有用的内容.这背后的基本原理是,在我的场景中,这个 S3 将被 CDN 或应用程序访问.我尝试将 '*' 放宽,但 Chrome 上的 CORS 策略抱怨我无法在 AllowedOrigins 中使用通配符条目!
  • <块引用><预><代码>[{允许的标题":[*"],允许的方法":[放置",邮政",获取",头",删除"],允许的起源":[cdn.myapp.com",myapp.com",https://cdn.myapp.com",https://myapp.com"],ExposeHeaders":[ETag"]}]

    1. react-player:我正在使用这样的 react-player(注意正在设置 forceHLS 选项,但它再次特定于我的用例.我认为这通常不是强制性的)

    <块引用>

    }宽度=100%"高度=100%"/>

    I'm developing a web site for provide a video on demand service by using React and AWS S3.
    I need to must authorize to watch videos.
    So I consider to use signed cookie when requesting.

    To request using curl was successful.

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

    But I can't get file at React.
    My code is there.

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

    Error message on Chrome(Image)

    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
    

    The request looks like not including cookies.
    How can I resolve the issue?

    解决方案

    Clearly, one of the issues is CORS policy enforcement. If you look at the response, you can see that the host/referrer (i.e. localhost:3000) is different from the target (OP has redacted but let's assume it to be blah.cloudfront.net). Even after addressing CORS, you need to make sure that Cloudfront and S3 are properly set up. I am laying out what worked for me:

    1. Assign custom domain to cloudfront such that the custom domain is a subdomain from where your app's frontend will run. In OP's case, he is using localhost:3000; most probably he is testing on his dev setup, but he must deploy this app at some domain: let's call this 'myapp.com'. So, he can assign a custom domain, say cdn.myapp.com to point to blah.cloudfront.net. You will need to create/import custom SSL certificate for the new custom domain; default cloudfront certificate won't work. Refer to this: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html[![enter image description here]2]2 The first one is having no custom domain, hence an empty CNAMEs column. The second one is having a custom domain, hence we have that one printed over there. You can verify that your custom domain got pointed to the cloudfront distribution this way.
    2. Cloudfront behaviour: I am assuming you have already set up trusted key group as at this point, you already have the signed cookie with you. HOWEVER, You will need to create custom Cache Policy and Origin Request Policy. See the following screenshots of the custom Cache Policy:and Origin Request Policy: The thing to notice is that you will need to whitelist these Headers: Origin, Access-Control-Request-Method, Access-Control-Allow-Origin, Access-Control-Request-Headers. (You might notice that Access-Control-Allow-Origin is not in the dropdown; just go ahead and type it!). Also, allow all cookies.
    3. S3 CORS configuration: Go to the S3 bucket and click on the permissions tab. Scroll down to the CORS configuration. Disclaimer: I just pasted what worked for me. The rationale behind this was that this S3 was going to be accessed by either CDN or app in my scenario. I tried putting '*' being lenient, but CORS policy on Chrome complained that I cannot use a wildcard entry in 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: I am using react-player like this (note forceHLS option being set, but it is again specific to my use case. I think this is not mandatory in general)

    <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%"
      />
    

    这篇关于如何使用来自 AWS S3 的预签名 cookie 在 ReactPlayer 上实现电影播放器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆