jQuery ajax設定
$.ajax({
....
xhrFields: {
withCredentials: true
},
....
});
如果是跨網域的ajax request,這段一定要加,不然就算server端的cors有設好,到瀏覽器這裡還是會擋掉http auth認證。同網域下(同http協定、網域和port)可省略。
Yii2 cors設定
在需認證的controller的behaviors加上下列設定
public function behaviors()
{
return [
....
'cors' => [
'class' => 'yii\filters\Cors',
'actions' => [
'{action-id}' => [
'Origin' => ['http://localhost:8080'],
'Access-Control-Allow-Credentials' => true,
],
],
],
....
];
}
我這邊是採用依action id覆寫cors設定的方式進行,也可以直接覆寫 yii\filters\Cors 的cors。
在跨網域要求http auth時,瀏覽器會要求回應的Access-Control-Allow-Origin標頭要明確指定網域,以判斷是否與呼叫的網域相符,若是使用 *會被瀏覽器擋掉。底下是server端沒有明確指定 Origin 時,瀏覽器輸出的錯誤。
Access to XMLHttpRequest at 'https://php56.test/cms2/runYii.php?r=api/authenticate/login' from origin 'http://localhost:8080' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
Access-Control-Allow-Credentials也必須被指定布林結果為true的值,直接設為true就可以了。底下是 Access-Control-Allow-Credentials採預設null時,瀏覽器輸出的錯誤。
Access to XMLHttpRequest at 'https://php56.test/cms2/runYii.php?r=api/authenticate/login' from origin 'http://localhost:8080' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
同一個網址的http auth request會被瀏覽器快取暫存,在關掉瀏覽器之前一直都會存在,如果已經成功認證過一次的話,在沒有關閉瀏覽器前再進行http auth,http auth對話方塊就不會再跳出,會一直沿用首次認證成功的帳密,很難實作登出的行為。