2017-07-07 348 views
0

我試圖設置使用Cloudfront HLS功能的視頻流,但我無法讓Hls.js在請求中發送我的憑證Cookie。hls.js CORS使用AWS Cloudfront問題與Cookies

我已經將Cloudfront配置爲轉發Cookie並轉發訪問控制標頭。我還設定了我的S3 CORS政策,以包括GET,HEAD。

我遇到的問題是,即使我設置了xhr.withCredentials = true並在會話中定義了cookie,當我使用chrome控制檯查看請求時,我可以看到HLS請求沒有餅乾。因此,我收到了來自雲端的錯誤響應,說我需要包含憑證Cookie。

代碼: 首先我向服務器發送ajax請求以生成cookie。服務器返回存儲會話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選項和GET請求不設置會話Cookie:

HLS OPTIONS請求:

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的響應:

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請求缺少餅乾:

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 

我了4天試圖弄清楚這一點。我做了大量的研究,但我無法弄清楚解決方案。我是CORS新手,所以也許我不理解某些原理。我認爲如果cookie被存儲在會話中,他們將被設置,如果您使用憑據啓用xhr,但似乎並非如此。

我注意到的另一件事是由HLS.js生成的GET請求不設置任何xmlhttprequest標頭。

感謝您的幫助:)

+1

來自example.com上的一個頁面的XHR請求將example.net發送的具有憑據的跨源請求發送給* example.net返回的cookie,而不是由example.com返回的cookie。 –

+0

所以我在這裏面臨着一個困境。我的web服務接口與亞馬遜aws生成cookie。問題是web服務正在不同的域中運行。這意味着我不能將任何cookie傳遞給我的CORS請求,除非cloudfront域名返回set-cookie頭文件?我不認爲雲端支持根據罐裝策略生成cookie作爲響應的一部分... 任何想法或建議? – Ismakun

+1

在CloudFront中創建第二個Origin,並將Web服務作爲原始主機名,並創建一個緩存行爲,其路徑指向到該新來源的服務路由。獲取Cookie的請求轉到CloudFront,CloudFront將其發送到原始位置以獲取Cookie,並通過CloudFront返回cookie,並將其設置在正確的域中。原則上這是有效的。它會與你的服務一起工作嗎? –

回答

0

我終於能夠使它工作。感謝邁克爾的幫助!原來,這是一個混合不理解CORS原則如何工作和正確配置aws服務。主要問題是通過使用cloudfront來服務web服務和s3存儲桶來避免跨域請求。我想補充的一個重要提示是,你在aws中所做的任何更改都必須等待它傳播。作爲一名新的aws開發者,我不知道這一點,並且非常沮喪地做出沒有任何效果的更改。這裏是解決方案:

1)創建您的S3存儲桶。

2)創建一個Cloudfront發行版。

3)在分配集中作爲默認原點的web服務域。

4)添加第二個原點並在分配中添加一個行爲,以將所有.m3u8和.ts文件轉發到您的S3存儲桶。

5)當您添加您的存儲桶來源時,請確保您標記限制訪問並更新存儲桶策略複選框。

6)在您的存儲桶分配行爲中,確保您轉發所有白名單標題和cookie。這可以全部在aws控制檯中設置。

7)如果您在服務中使用不同的端口,請確保在分配中設置這些端口。

8)轉到您的S3存儲設置和更新CORS配置以下內容:

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

重要的是,如果你使用的是HLS.js設置以下配置:

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); 

其他重要注意事項:

當您使用您的網絡服務提供cookie時,您可以將路徑設置爲「/」,它將應用於您域中的所有請求。