如何使用来自 AWS S3 的预签名 cookie 在 ReactPlayer 上实现电影播放器 [英] How can I implement a movie player on ReactPlayer with presigned cookies from AWS S3
问题描述
我正在开发一个使用 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.
<块引用><预><代码>[{允许的标题":[*"],允许的方法":[放置",邮政",获取",头",删除"],允许的起源":[cdn.myapp.com",myapp.com",https://cdn.myapp.com",https://myapp.com"],ExposeHeaders":[ETag"]}]
- 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:
- 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.
- 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.
- 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" ] } ]
- 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屋!