Slide 1

Slide 1 text

CORSをちゃんと理解する 2021/07/07 #4 atma勉強会 nyk510

Slide 2

Slide 2 text

質問です。

Slide 3

Slide 3 text

CORSって知ってますか?

Slide 4

Slide 4 text

CORS Cross-Origin Resource Sharing オリジン間リソース共有

Slide 5

Slide 5 text

名前ぐらいは聞いたことある? エラーで見たことはある? よくわかんない?けどなんかヘッダーに設定 したら直るやつ?

Slide 6

Slide 6 text

ちゃんと理解しましょう!

Slide 7

Slide 7 text

CORSの定義 追加の HTTP ヘッダーを使用して、あるオリジンで動作しているウェブ アプリケーションに、異なるオリジン にある選択されたリソースへのア クセス権を与えるようブラウザーに指示するための仕組みです。

Slide 8

Slide 8 text

CORSの定義 追加の HTTP ヘッダーを使用して、あるオリジンで動作しているウェブ アプリケーションに、異なるオリジン にある選択されたリソースへのア クセス権を与えるようブラウザーに指示するための仕組みです。

Slide 9

Slide 9 text

オリジンて何?

Slide 10

Slide 10 text

オリジン URLのプロトコルとホスト(ドメイン)、ポートで識別されるもの 全部が一緒だと同じオリジンとなる 例えば https://hoge.com に対して ● 同じ: https://hoge.com/foo/bar.html / https://hoge.com:443 ● 違う: http://hoge.com / https://api.hoge.com

Slide 11

Slide 11 text

CORSの定義 追加の HTTP ヘッダーを使用して、 あるオリジンで動作しているウェブアプリケーション(ex: フロントエンド)に、 異なるオリジン にある選択されたリソース (ex: バックエンド)への アクセス権を与えるようブラウザーに指示するための仕組みです。

Slide 12

Slide 12 text

CORSの定義からわかること ● 特定のオリジンのアプリから、別のオリジンのデータ(リソース)を 取ってくる権限を定めたものである。 ● ブラウザーの仕組みである ○ 例えば terminal からのアクセスは関係ない

Slide 13

Slide 13 text

なんでこんなのがあるの? ● セキュリティ的観点から同じオリジン以外の情報を取ってこれないようにしてい るから ● 取ってこようとしている先のオリジンが許可した時だけデータのやり取り(リソー ス共有)ができるホワイトリスト方式になっている。 以下の説明では ● ブラウザで表示されているオリジン: Alice ● 異なるオリジン: Blob として説明します。

Slide 14

Slide 14 text

ブラウザは、どうやって許可されているかを知るの? ● ブラウザは一度普通にBobへとリクエストを送りBobはレスポンスを返す ● ブラウザはレスポンス内の Access-Control-Allow-Origin ヘッダーをみる ○ リクエスト元の Origin がこの中に入っていれば許可されたとみなす。 ○ ワイルドカード * 指定も出来る。この場合何でも許可されたとみなす。 ○ それ以外は許可されていないリクエストとみなす。 ● 許可されている時 ○ レスポンスを展開して js からアクセス可能 ● 許可されていない時 ○ ブラウザが強制的に処理を止めてエラーになる. js からは「何かしらのエ ラーが起こった」しかわからない(これはセキュリティのため)

Slide 15

Slide 15 text

Bob から見ると… ● 自分を呼び出してもオッケーなサイトを Access-Control-Allow-Origin に入れる ● するとそれ以外のオリジンでは、ブラウザからBobの情報を参照できない ● すくなくともブラウザでアクセスして悪さする外部サイトの脅威を減らせて良い

Slide 16

Slide 16 text

アクセス許可の方法 ● 単純リクエスト ● プリフライトリクエスト

Slide 17

Slide 17 text

単純リクエスト ● 相手サーバ Bob に副作用を起こさないようなリクエスト ● 先のフローと同様のやり方で許可を判定する ● method: GET/HEAD/POST ● content-type: application/x-www-formurlencoded, multipart/form-data, text/plan

Slide 18

Slide 18 text

プリフライトリクエスト ● 単純リクエストでないものが該当 ・ ex:) POSTで json を送りたい フロー ● 許可を取るリクエスト (OPTION) を自動的にブラウザが Bob へ送信 ○ 今からこういうことするのでオッケーですかというお伺い ○ これがプリフライトリクエスト ● Bobは要求に従って何を許可するかを返信 ○ ex). POSTはOK / application/json はOK ● ブラウザは許可内容をみる (Bobは何がOKって言っている?) ○ やりたいリクエストが許可なら、Bobへ本体のリクエストを送信 ○ 許可されていなければエラーにする(jsからは失敗内容はわからない)

Slide 19

Slide 19 text

ブラウザからのリクエストとレスポンス ● 何故か method が単数形と複数形あるがこれはお伺い建てるのはひとつだけだから ● リクエストだけ origin は origin なのは謎 要求 リクエストヘッダー レスポンスヘッダー methodに対する許可 Access-Control-Request-Method Access-Control-Allow-Methods ヘッダーに対する許可 Access-Control-Requests-Header Access-Control-Allow-Headers オリジンに対する許可 Origin Access-Control-Allow-Origin

Slide 20

Slide 20 text

具体例を見ましょう。

Slide 21

Slide 21 text

例: ぐるぐる フロントエンド: https://guruguru.science バックエンド: https://api.guruguru.science これらは別 Origin なので Access-Control-Allow-Origin をバックエンド 側に仕込んでいないとフロントをブラウザで開いた時バックエンドの情 報は表示できない。

Slide 22

Slide 22 text

例: ぐるぐる・単純リクエスト https://api.guruguru.science/competitions/17/ ブラウザからAPIへ送信して いるリクエストヘッダー APIからブラウザへ返信され たレスポンスヘッダー

Slide 23

Slide 23 text

例: ぐるぐる・単純リクエスト https://api.guruguru.science/competitions/17/ リクエストの method が GET なので 単純リクエストとしてブラウザで処理される。

Slide 24

Slide 24 text

例: ぐるぐる・単純リクエスト https://api.guruguru.science/competitions/17/ APIが allow-origin に www.guruguru.science を入 れている → ブラウザで表示OK

Slide 25

Slide 25 text

例: ぐるぐる・プリフライトつきリクエスト ログインページ: https://api.guruguru.science/auth/login/ POSTでかつusername/passwordを送信するため単純ではない。 おさらい ● はじめOPTIONによるプリフライトで確認 ● 確認がとれれば本体のPOSTを送信

Slide 26

Slide 26 text

例: ぐるぐる・OPTIONによるプリフライトで確認 ブラウザはこれから何を送ろうとしているかをOPTION をつかってお伺い (プリフライトリクエスト) この場合だと 「MethodはPOST / ヘッダーには content-type / オリ ジンは https://www.guruguru.science ですがよろしい でしょうか」

Slide 27

Slide 27 text

例: ぐるぐる・OPTIONによるプリフライトで確認 APIはブラウザの各種 requests に対して何を許可 しているかを返す。 API「POSTはOK・ヘッダーも content-type は オッケーで、オリジンもOKだよ!」

Slide 28

Slide 28 text

例: ぐるぐる・確認がとれれば本体のPOSTを送信 今回の場合別オリジン(API)から許可がもらえたの で本体のPOST処理を送信。 もう許可はもらえているのでこのリクエストに Access-Control-Request 系のヘッダーはない。

Slide 29

Slide 29 text

まとめ ● CORSはオリジンの違うサーバにたいしてブラウザからアクセスするときの制御に 関する仕組みである。 ● リクエストの種類によってプロトコルが異なる。

Slide 30

Slide 30 text

参考資料 ● https://developer.mozilla.org/ja/docs/Web/HTTP/CORS ● 安全なウェブアプリケーションの作りかた・3.3章