質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

CORS

CORSとはCross-Origin Resource Sharingの頭文字をとったもので、ブラウザがオリジン以外のサーバからデータを取得するシステムのことです。

Q&A

解決済

1回答

2845閲覧

CORS でクッキーが保存できない

nico25

総合スコア830

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

CORS

CORSとはCross-Origin Resource Sharingの頭文字をとったもので、ブラウザがオリジン以外のサーバからデータを取得するシステムのことです。

0グッド

0クリップ

投稿2019/10/15 12:15

編集2019/10/15 13:17

お世話になっております。
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

以上になります。
目を通していただき、ありがとうございます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

スペルミスでした... credentials の s が抜けてました... orz
お騒がせして申し訳ございませんでした。

javascript

1fetch( 2 'https://127.0.0.1:5000/', 3 { 4 mode: 'cors', 5 credentials: 'include', // <--- s が抜けてました... 6 }).then(function(response) { 7 console.log(response); 8 })

投稿2019/10/15 13:54

編集2019/10/15 13:55
nico25

総合スコア830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問