Fetch APIを使用している場合(実際にはfetch polyfillを介して)Safariにサーバの応答からSet-Cookie
を正常に適用させることができません。 FFとChromeでも同じコードが正しく動作します(ネイティブとポリフィルの両方を使用してテスト済みfetch
)。SafariがJS Fetch APIを使用してCORS Cookieを設定していない
- ドメイン間で要求があります。
- はい、私は
credentials: true
を設定しています。 - サーバーは
Set-Cookie
ヘッダーで応答します。 - その後のリクエストはCookieリクエストヘッダーを使用してChromeとFFから送信されますが、Safariでは送信されません。
- リクエストはHTTPSを使用します(証明書は自己署名され、開発ドメイン上にありますが、Safariは通常のリクエストで受け付けているようです)。および
誰かが問題の原因を知っていますか?
私はドキュメントを読んで、closed bug reportsの多くを見てきました。私が何かを見逃していなければ、おそらく問題は'default browser behaviour'のクッキーとCORSを扱うことだと思います。フェッチするのではなく(ポリフィルのソースコードを読むと、100%クッキーを知らないようです)。いくつかのバグレポートには、不正な形式のサーバー応答がCookieの保存を妨げる可能性があることが示唆されています。
私のコードは次のようになります。
function buildFetch(url, init={}) {
let headers = Object.assign({}, init.headers || {}, {'Content-Type': 'application/json'});
let params = Object.assign({}, init, { credentials: 'include', headers });
return fetch(`${baseUrl}${url}`, params);
}
buildFetch('/remote/connect', {method: 'PUT', body: JSON.stringify({ code })})
.then(response => response.json())
.then(/* complete authentication */)
実際の認証要求は以下の通りです。 Safariはコピー/貼り付けが難しいため、正確なリクエスト/レスポンスデータを取得するためにcURLを使用しています。
curl 'https://mydevserver:8443/api/v1/remote/connect' \
-v \
-XPUT \
-H 'Content-Type: application/json' \
-H 'Referer: http://localhost:3002/' \
-H 'Origin: http://localhost:3002' \
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8' \
--data-binary '{"token":"value"}'
* Trying 127.0.0.1...
* Connected to mydevserver (127.0.0.1) port 8443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
* Server certificate: mydevserver
> PUT /api/v1/remote/connect HTTP/1.1
> Host: mydevserver:8443
> Accept: */*
> Content-Type: application/json
> Referer: http://localhost:3002/
> Origin: http://localhost:3002
> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8
> Content-Length: 15
>
* upload completely sent off: 15 out of 15 bytes
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: http://localhost:3002
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Api-Key, Device-Key
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
< Access-Control-Expose-Headers: Date
< Content-Type: application/json; charset=utf-8
< Content-Length: 37
< Set-Cookie: express:sess=[SESSIONKEY]=; path=/; expires=Fri, 17 Feb 2017 15:30:01 GMT; secure; httponly
< Set-Cookie: express:sess.sig=[SIGNATURE]; path=/; expires=Fri, 17 Feb 2017 15:30:01 GMT; secure; httponly
< Date: Fri, 17 Feb 2017 14:30:01 GMT
< Connection: keep-alive
<
* Connection #0 to host mydevserver left intact
{"some":"normal","response":"payload"}