お世話になっております。
CORS でクッキーを保存することができず、このたび質問させていただきました。
何か思い当たることなどありましたら、ご教示いただけると幸いでございます。
環境
以下のようにサーバを2つ立ち上げました。
名称 | URL |
---|---|
API サーバ | https://127.0.0.1:5000/ |
クライアント | https://127.0.0.1:5001/ |
◯ API サーバ
API サーバには以下のようなレスポンスを返すようにしています。
$ curl -i https://127.0.0.1:5000/ HTTP/1.0 200 OK Content-Type: text/plain; charset=utf-8 Content-Length: 20 Access-Control-Allow-Origin: https://127.0.0.1:5001 Access-Control-Allow-Method: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS Access-Control-Allow-Headers: Content-type,Accept,X-Custom-Header Access-Control-Allow-Credentials: true Access-Control-Max-Age: 86400 set-cookie: connect.sid=s%3AM9NQy3hz5cLb3kW6htuybWE6nEX1_iL6.ENXqiTfVPMQVyP%2FGFZ9pshnC87D7rX5%2BM48mjVqwR7s; Path=/; HttpOnly; Secure Server: Werkzeug/0.16.0 Python/3.7.4 Date: Tue, 15 Oct 2019 11:57:47 GMT This is a sample page. $
◯ クライアント
"This is a sample page." とだけ表示されるページを作成しました。
試したこと
◯ その1 成功 - ブラウザから直接
https://127.0.0.1:5000/ にブラウザから直接アクセス
-> 問題なくクッキーが保存されました。
◯ その2 成功 - CORS ではない fetch
https://127.0.0.1:5000/ にブラウザでアクセス
保存されたクッキーを消す
デベロッパツールのコンソールから fetch を使い、以下のスクリプトを実行します。
javascript
1fetch( 2 'https://127.0.0.1:5000/', 3 { 4 mode: 'cors', 5 credential: 'include', 6 }).then(function(response) { 7 console.log(response); 8 })
-> 問題なくクッキーが保存されました。
その3 失敗 - CORS で fetch
https://127.0.0.1:5001/ にブラウザでアクセス
デベロッパツールのコンソールから fetch を使い、上記のスクリプトを実行しました。
-> クッキーは保存され ない。
結果の詳細は、以下のような具合です。
ブラウザ | コンソール | ネットワーク | ストレージ |
---|---|---|---|
Chrome | エラーは起こらない | Set-Cookie ヘッダが表示される | クッキーは保存され ない |
Safari | エラーは起こらない | Set-Cookie ヘッダが表示され ない | クッキーは保存され ない |
Chrome はヘッダーにさえ表示されません。
ただ Safari の方は、クッキーを認識してくれてはいるように見えています。
参考にさせていただいているサイト
主にこちらを参考にしました。
また以下の Stackoverflow の記事から、
もしかして、そもそもできないのかなと疑問を抱いております。
追記された回答にサブドメインに登録すれば使えるよ、
と書かれていたので、hosts ファイルから api.example.com, example.com を設定して、
似たようなことをしてみたのですが、ダメでした。
Safari not setting CORS cookies using JS Fetch API - Stackoverflow
I find it pretty enraging that this is a "working as intended" behaviour of Safari, though I understand their motivation. XHR (and presumably native fetch when it lands natively) does not support the setting of third-party cookies at all.
This failure is completely transparent because it is handled by the browser outside of the scripting context, so client-based solutions are not really going to be possible.
環境の補足
◯ 使用しているサーバ
サーバは Flask を使用しています。
python
1# api.py 2from flask import Flask 3from flask import Response 4 5app = Flask(__name__) 6 7@app.route("/") 8def index(): 9 resp = Response("Hello, world!") 10 resp.headers['Access-Control-Allow-Origin'] = 'https://127.0.0.1:5001' 11 resp.headers['Access-Control-Allow-Method'] = 'GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS' 12 resp.headers['Access-Control-Allow-Headers'] = 'Content-type,Accept,X-Custom-Header' 13 resp.headers['Access-Control-Allow-Credentials'] = 'true' 14 resp.headers['Access-Control-Max-Age'] = '86400' 15 resp.headers['Content-Type'] = 'text/plain; charset=utf-8' 16 resp.headers['set-cookie'] = 'connect.sid=s%3AM9NQy3hz5cLb3kW6htuybWE6nEX1_iL6.ENXqiTfVPMQVyP%2FGFZ9pshnC87D7rX5%2BM48mjVqwR7s; Path=/; HttpOnly; Secure' 17 return resp
python
1# clietn.py 2from flask import Flask 3 4client = Flask(__name__) 5 6@client.route('/') 7def index(): 8 return "This is a sample page."
◯ SSL 秘密鍵と証明書
mkcert を使って、オレオレ証明書を発行しています。
mkcert 127.0.0.1
以上になります。
目を通していただき、ありがとうございます。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。