我正在尝试使用 Cloudfront HLS 功能设置视频流,但我无法让 Hls.js 在请求中发送我的凭据 cookie。
我已经将 Cloudfront 配置为转发 cookie 和转发访问控制标头。我还设置了 S3 CORS 策略以包括 GET、HEAD。
我遇到的问题是,即使我设置 xhr.withCredentials=true 并且 cookie 是在会话中定义的,当我使用 chrome 控制台查看请求时,我可以看到 HLS 请求没有 cookie。结果我收到了来自 cloudfront 的错误响应,说我需要包含凭证 cookie。
代码:
首先,我向服务器发出 ajax 请求以生成 cookie。服务器返回三个 Set-Cookies 标头,在浏览器中存储为会话 cookie:
$.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' }
});
存储 cookie 后,将调用测试函数以使用 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();
}
正如您在下面看到的,HLS OPTIONS 和 GET 请求不会设置会话 cookie:
HLS 选项请求:
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
云前响应:
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 后续 GET 请求缺少 cookie:
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
我花了四天时间试图解决这个问题。我做了很多研究,但我就是找不到解决方案。我是 CORS 的新手,所以也许我不理解某些原理。我认为如果 cookie 存储在会话中,如果您使用凭据启用了 xhr,它们就会被设置,但情况似乎并非如此。
我注意到的另一件事是 HLS.js 生成的 GET 请求没有设置任何 xmlhttprequest 标头。
感谢您的帮助 :)