hls.js将AWS Cloudfront问题与Cookies一起使用 [英] hls.js CORS using AWS Cloudfront issues with Cookies

查看:195
本文介绍了hls.js将AWS Cloudfront问题与Cookies一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Cloudfront HLS功能设置视频流,但是我无法让Hls.js在请求中发送我的凭据cookie。



我已经将Cloudfront配置为转发Cookie和转发访问控制标头。我还设置了S3 CORS策略以包括GET,HEAD。



我遇到的问题是,即使我将xhr.withCredentials = true设置为cookie是在会话中定义的,当我使用chrome控制台查看请求时,我可以看到HLS请求中没有cookie。结果,我从cloudfront收到一个错误响应,说我需要包括凭据cookie。



代码:
首先,我向服务器执行ajax请求以生成cookie。服务器返回在浏览器中存储为会话cookie的三个Set-Cookies标头:

  $。ajax(
{
类型: GET,
网址: http://subdomain.mydomain.com:8080/service-
webapp / rest / resourceurl / cookies / 98400738-a415-4e32-898c- 9592d48d1ad7',
成功:函数(数据){
playMyVideo();
},
标头:{ Authorization:'Bearer XXXXXX'}
}) ;

一旦存储了cookie,就会使用HLS.js调用测试功能来播放我的视频:

 功能test(){
if(Hls.isSupported()){
var video = document.getElementById ('视频');
var config = {
debug:true,
xhrSetup:function(xhr,url){
xhr.withCredentials = true; //发送cookie
xhr.setRequestHeader( Access-Control-Allow-Headers, Content-Type,Accept,X-Requested-With);
xhr.setRequestHeader( Access-Control-Allow-Origin, http://sybdomain.domain.com:8080);
xhr.setRequestHeader( Access-Control-Allow-Credentials, true);
}
};
var hls = new Hls(config);
//将它们绑定在一起
hls.attachMedia(video);
hls.on(Hls.Events.MEDIA_ATTACHED,function(){
console.log( video and hls.js现在绑定在一起!);
hls.loadSource( http ://cloudfrontDomain.net/small.m3u8);
hls.on(Hls.Events.MANIFEST_PARSED,函数(事件,数据){
console.log(已加载清单,找到了 +数据.levels.length +质量等级);
});
});
}
video.play();
}

您可以在下面看到HLS OPTIONS和GET请求未设置会话Cookie :



HLS选项请求:

  OPTIONS / hls / 98400738- a415-4e32-898c-9592d48d1ad7 / small.m3u8 HTTP / 1.1 
主机:cloudfrontDomain.net
连接:keep-alive
访问控制请求方法:GET
来源:subdomain.mydomain.com:8080
用户代理:Mozilla / 5.0(X11; Linux x86_64)AppleWebKit / 537.36(KHTML,例如Gecko)Chrome / 59.0.3071.104 Safari / 537.36
Access-Control-请求标头:access-control-allow-credentials,access-control-allow-headers,access-control-allow-origin
接受:* / *
推荐人:http://subdomain.mydomain。 com:8080 / play.html
接受编码:gzip,缩小
接受语言:en-US,en; q = 0.8,es; q = 0.6

CloudFront响应:

  HTTP / 1.1 200 OK 
内容长度:0
连接:keep-alive
日期:2017年7月7日星期五00:16:31 GMT
Access-Control-Allow-Origin:http://subdomain.mydomain.com:8080
Access-Control-Allow-Methods:GET,HEAD
Access-Control-Allow-Headers:访问控制-allow-credentials,access-control-allow-headers,access-control-allow-origin
Access-Control-Max-Age:3000
Access-Control-Allow-Credentials:true
服务器:AmazonS3
变化:来源,访问控制请求标题,访问控制请求方法
年龄:845
X缓存:从云端
命中通过: 1.1 cloudfrontDomain.net(CloudFront)
X-Amz-Cf-Id:XXXXXX

HLS随后的GET请求缺少cookie:

  GET /hls/98400738-a415-4e32-898c-9592d48d1ad7/small.m3u8 HTTP / 1.1 
主机:cloudfrontDomain.net
连接:keep-alive
来源:http://subdomain.mydomain.com:8080
用户代理:Mozilla / 5.0(X11; Linux x86_64)AppleWebKit / 537.36(KHTML,like Gecko)Chrome / 59.0.3071.104 Safari / 537.36
Access-Control-Allow-Origin:http://subdomain.mydomain.com:8080
Access-Control -Allow-Credentials:true
Access-Control-Allow-Headers:内容类型,接受,X-Requested-with
Accept:* / *
引用者:http:// subdomain。 mydomain.com:8080/play.html
接受编码:gzip,缩小
接受语言:zh-cn,en; q = 0.8,es; q = 0.6

我花了4天的时间来弄清楚这一点。我已经做了很多研究,但我只是想不出解决方案。我是CORS的新手,所以也许我不了解某些原理。我想如果将cookie存储在会话中,如果您使用凭据启用了xhr,它们就会被设置,但事实并非如此。



我注意到的另一件事是由HLS.js生成的GET请求未设置任何xmlhttprequest标头。



感谢您的帮助:)

解决方案

我终于能够使它起作用。感谢迈克尔的帮助!原来,这是由于不了解CORS原理如何工作以及正确配置AWS服务。主要问题是通过使用cloudfront为您的Web服务和s3存储桶提供服务来避免跨域请求。我要补充的一个重要说明是,您对aws所做的任何更改都必须等待其传播。作为一个新的AWS开发人员,我不知道这一点,对进行无效的更改感到非常沮丧。解决方案如下:



1)创建您的S3存储桶。



2)创建Cloudfront发行版。 / p>

3)在分配集中,将您的Web服务域作为默认来源。



4)添加第二个起源并在分发中添加一个行为以将所有.m3u8和.ts文件转发到您的S3存储桶。



5)添加存储桶起源时,请确保标记了限制访问并更新存储桶策略复选框。



6)在存储桶分发行为中,请确保转发所有白名单标头和cookie。



7)如果您在服务中使用其他端口,请确保在分发中也设置了这些端口。



8)转到S3存储桶设置,并将CORS配置更新为以下内容:

 <?xml版本= 1.0编码= UTF-8?> 
< CORSConfiguration xmlns = http://s3.amazonaws.com/doc/2006-03-01/>
< CORSRule>
< AllowedOrigin> *< / AllowedOrigin>
< AllowedMethod> GET< / AllowedMethod>
< AllowedMethod> HEAD< / AllowedMethod>
< MaxAgeSeconds> 3000< / MaxAgeSeconds>
< AllowedHeader> *< / AllowedHeader>
< / CORSRule>
< / CORSConfiguration>

重要的是,如果您使用HLS.js来设置以下配置,则很重要:

  var config = {
debug:true,
xhrSetup:function(xhr,url){
xhr .withCredentials = true; //发送cookie
xhr.setRequestHeader( Access-Control-Allow-Headers, Content-Type,Accept,X-Requested-With);
xhr.setRequestHeader( Access-Control-Allow-Origin, http://sybdomain.domain.com:8080);
xhr.setRequestHeader( Access-Control-Allow-Credentials, true);
}
};
var hls = new Hls(config);

其他重要说明:



当您在您的网络服务中提供Cookie,您可以将路径设置为 /,它将应用于您域中的所有请求。


I'm trying to set up a video streaming using Cloudfront HLS capabilities but I'm having trouble getting Hls.js to send my credential cookies in the request.

I already have Cloudfront configured to forward cookies and to forward Access-control headers. I also have set my S3 CORS policies to include GET, HEAD.

The problem I'm having is that even though I'm setting the xhr.withCredentials=true and the cookies are defined in the session, when I look at the request using chrome console, I can see that the HLS request has no cookies. As a result I get an error response from cloudfront saying I need to include the credential cookies.

Code: First I do an ajax request to my server to generate the cookies. The server returns three Set-Cookies headers stored as session cookies in the browser:

$.ajax(
{
type: 'GET',
url: 'http://subdomain.mydomain.com:8080/service-
webapp/rest/resourceurl/cookies/98400738-a415-4e32-898c-9592d48d1ad7',
success: function (data) {
        playMyVideo();
},
headers: { "Authorization": 'Bearer XXXXXX' }
});

Once the cookies are stored the test function is called to play my video using HLS.js:

function test(){
  if (Hls.isSupported()) {
  var video = document.getElementById('video');
  var config = {
    debug: true,
    xhrSetup: function (xhr,url) {
        xhr.withCredentials = true; // do send cookie
    xhr.setRequestHeader("Access-Control-Allow-Headers","Content-Type, Accept, X-Requested-With");
        xhr.setRequestHeader("Access-Control-Allow-Origin","http://sybdomain.domain.com:8080");
    xhr.setRequestHeader("Access-Control-Allow-Credentials","true");
    }
  };
  var hls = new Hls(config);
  // bind them together
  hls.attachMedia(video);
  hls.on(Hls.Events.MEDIA_ATTACHED, function () {
    console.log("video and hls.js are now bound together !");
    hls.loadSource("http://cloudfrontDomain.net/small.m3u8");
    hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {
      console.log("manifest loaded, found " + data.levels.length + " quality level");
    });
  });
}
video.play();
}

As you can see below HLS OPTIONS and GET request do not set the session cookies:

HLS OPTIONS request:

OPTIONS /hls/98400738-a415-4e32-898c-9592d48d1ad7/small.m3u8 HTTP/1.1
Host: cloudfrontDomain.net
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: subdomain.mydomain.com:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36
Access-Control-Request-Headers: access-control-allow-credentials,access-control-allow-headers,access-control-allow-origin
Accept: */*
Referer: http://subdomain.mydomain.com:8080/play.html
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8,es;q=0.6

CloudFront response:

HTTP/1.1 200 OK
Content-Length: 0
Connection: keep-alive
Date: Fri, 07 Jul 2017 00:16:31 GMT
Access-Control-Allow-Origin: http://subdomain.mydomain.com:8080
Access-Control-Allow-Methods: GET, HEAD
Access-Control-Allow-Headers: access-control-allow-credentials, access-control-allow-headers, access-control-allow-origin
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
Server: AmazonS3
Vary: Origin,Access-Control-Request-Headers,Access-Control-Request-Method
Age: 845
X-Cache: Hit from cloudfront
Via: 1.1 cloudfrontDomain.net (CloudFront)
X-Amz-Cf-Id: XXXXXX

HLS subsequent GET request missing the cookies:

GET /hls/98400738-a415-4e32-898c-9592d48d1ad7/small.m3u8 HTTP/1.1
Host: cloudfrontDomain.net
Connection: keep-alive
Origin: http://subdomain.mydomain.com:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36
Access-Control-Allow-Origin: http://subdomain.mydomain.com:8080
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type, Accept, X-Requested-With
Accept: */*
Referer: http://subdomain.mydomain.com:8080/play.html
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8,es;q=0.6

I've spent 4 days trying to figure this out. I've done plenty of research but I just can't figure out the solution. I'm new to CORS so maybe I'm not understanding some principle. I thought if the cookies are stored in the session they would get set if you enabled xhr with credentials but it doesn't seem to be the case.

Another thing I noted is that the GET request generated by HLS.js is not setting any xmlhttprequest header.

Thanks for your help :)

解决方案

I was finally able to make it work. Thanks Michael for helping! Turns out it was a mix of not understanding how CORS principles work and properly configuring aws services. The main issue is to avoid cross domain requests by using cloudfront to serve both your webservice and s3 bucket. One important note I want to add is that any change you make in aws you have to wait for it to propagate. As a new aws dev I didn't know that and got very frustrated making changes that had no effect. Here is the solution:

1) Create your S3 bucket.

2) Create a Cloudfront distribution.

3) In the distribution set as the default origin your web-service domain.

4) Add a second origin and add a behavior in the distribution to forward all .m3u8 and .ts files to your S3 bucket.

5) When you add your bucket origin make sure you mark restrict access and also update bucket policy checkboxes.

6) In your bucket distribution behavior make sure you forward all white list headers and cookies. This can all be set in aws console.

7) If you are using different ports in your service make sure you set those too in the distribution.

8) Go to your S3 bucket settings and update the CORS config to the following:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration> 

It is important that if your are using HLS.js to set the following config:

var config = {
debug: true,
xhrSetup: function (xhr,url) {
xhr.withCredentials = true; // do send cookie
xhr.setRequestHeader("Access-Control-Allow-Headers","Content-Type, Accept, X-Requested-With");
    xhr.setRequestHeader("Access-Control-Allow-Origin","http://sybdomain.domain.com:8080");
xhr.setRequestHeader("Access-Control-Allow-Credentials","true");
}
};
var hls = new Hls(config);

Other important notes:

When you serve a cookie with your web service you can set the Path to be "/" and it will apply to all request in your domain.

这篇关于hls.js将AWS Cloudfront问题与Cookies一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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