Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9138

Node.js(Express)でCORSを許可する

$
0
0
はじめに 開発環境にデプロイする際にセキュリティの観点から「APIを叩いてもCORSで弾かれた」ため、それに伴うアウトプットをします。 ※個人ブログから技術的アウトプットはQiitaへ引っ越ししたので、こちらは過去に書いたブログとなります。 エラーの事象 開発環境にデプロイする際にセキュリティの観点から 「 APIを叩いてもCORSで弾かれた 」です。 背景 まず冒頭の 開発環境にデプロイする際に ということですが、今までローカル環境では、nuxt.config.jsの設定でproxyサーバーを立てることができていたので、サーバー側でCORS対応をする必要ありませんでした。 しかし、Firebaseのhostingにデプロイした際にproxyサーバーを立てることができずに、結果、冒頭に書いたAPIを叩いてもCORSで弾かれました。   調べてみると、セキュリティの観点から、オリジン(HTMLが置かれたサーバー)以外のサーバーからデータを取得すること(=CORS:Cross-Origin-Resource-Sharing)を、現在のブラウザでは許可していないようです。 こちらを回避するためには、サーバー側にて、CORSを許可する必要とのこと。 CORSとは そもそもCORS、CORSと書いてるが、CORSとはなにか? 僕は先日始めてこの英単語の組み合わせ達に鉢合わせました。 読み方: コルス Cross-Origin Resource Sharing の略 訳すと「 オリジン間リソース共有 」 ではこのオリジンとはなにか?? オリジンは ドメイン と似た概念似てるようで全く異なる概念 ドメイン(例):google.com オリジン(例):https://www.google.com:443 つまり、ドメインとの 見た目上の違い はプロトコルとホストとポート番号を含んでいるという点 オリジン == プロトコル + ホスト + ドメイン + ポートナンバー ※ URLを構成する要素を整理について ※ クエリストロングではなく、 クエリストリング(文字列) です....笑  何を強くしてるねん.... URLを構成する要素を整理についてはこのツイートがわかりやすい ※ クエリストロングではなく、 クエリストリング(文字列)だと思われる URLを構成する要素を整理するとこうなる!デザインの勉強するまで深く考えたことなかった。笑 pic.twitter.com/kyGRMS1Xxk— 東 莉緒 / Rio Azuma (@rio310mink) September 23, 2020   オリジンを踏まえた上でCORSとは? CORS は日本語訳すると オリジン間リソース共有 (上述)。 つまり CORS とは、あるオリジンで動いている Web アプリケーションに対して、別のオリジンのサーバーへのアクセスをオリジン間 HTTP リクエストによって許可できる仕組みのことをいう 許可できるようになるまでの仕組みとしては、サーバーからのレスポンスにリソースの共有を許可するための特別なヘッダーを追加して動作できるようになる なぜCORSが必要なのか? これは上述のように、昨今のブラウザでは、フロントエンドJavaScriptから違うドメインへのアクセスに対して、CORSがサーバ側で許可されている場合を除き、セキュリティ上の問題からアクセスをしない仕様となっているため。 どんな時にクロスオリジンにアクセスするか? 基本的には、 XML HttpRequest(Ajax) FetchAPIでの非同期通信する時 などって思ってOK CORSのリクエストの種類 XMLHttpRequestを用いてオリジン間リソース共有がどのように動作するかを説明 リクエストによっては CORSを引き起こさないものがあるみたい。 そこでリクエストを2つ(単純リクエストとプリフライト リクエスト)に分けます。 ▼ 単純リクエスト 上述通り、CORSを引き起こさないもの。 例えば以下のメソッド GET POST HEAD ▼プリフライト リクエスト 単純リクエストとは異なり、リクエストの始めに OPTIONSメソッド で対象の異なるオリジンにリクエストを送り、実際のリクエストを送っても問題ないか確認するリクエストをプリフライト リクエストという 該当するリクエストは以下 PUT DELETE CONNECT OPTIONS TRACE PATCH  HTTPのOPTIONSメソッドとは HTTPで使われるメソッドといえば、上記のようなGETやPOSTが一般。 一方、OPTIONSメソッドは、これらのメソッドのうち、サーバーがどのメソッドをサポートしているかを調査するためのメソッド。 どこで使われるのかと言うと、ブラウザがCORSを検出した場合、実際のメインメソッド(GETやPOST)を投げる前に、OPTIONSメソッドによる検査を実行するような仕様になっています。そしてプリフライトリクエストを投げて、そこからOKであれば、204でレスポンスが返ってきて、そこからメインリクエスト(GETメソッド)が返ってくる。つまりレスポンスが2個返ってくる!(下図) つまり、APIサーバの実装には CORSを有効にする(HTTPレスポンスヘッダにAccess-Control-Allow-Origin等の実装)に加え、 OPTIONSメソッドの実装 が必要ということ express で CORS を許可する 今回は、CORS とはなにか?が中心だったので、最後にかんたんにコードで説明します。 CORSを許可するための実装には、 XHR を使う場合 Fetchを使う場合 axios を使う場合 Expressを使う場合 などがあり、開発推進課ではNodeのExpressを使っているので、それを使ってCORS を許可する。 ▼cors モジュールをimport  Node.js import cors from 'cors'; app.use(cors()); ちなみに Node.js app.use(cors());  だと フルで CORS 周りの設定を許可していることになるみたいです。 また、特定の API に対して個別にCORSを許可する場合は、以下のように Node.js api.use(cors(corsOptions)); で指定できます。 例えば、ローカルホストや開発環境だったら、どこからでも叩けるようにして、それ以外はCORSで弾くみたいな感じの条件分岐で記述していく感じ。 まとめ ブラウザでは、フロントエンドから違うドメインへのアクセスに対して、CORSがサーバ側で許可されている場合を除き、セキュリティ上の問題からアクセスできない場合が多い このアクセスを許可するために、CORSを使う CORSとは、「あるオリジンで動いている Web アプリに対して、別のオリジンのサーバーへのアクセスをオリジン間 HTTP リクエストによって許可できる仕組み、ルール」のこと 許可するためには、CORSを有効にする(HTTPレスポンスヘッダーにAccess-Control-Allow-Origin等の実装)に加え、OPTIONSメソッドの実装する必要がある HTTPで使われるメソッドといえば、GETやPOSTが一般だが、一方、OPTIONSメソッドは「サーバーがどのメソッドをサポートしているかを調査するためのメソッド」。 プリフライトリクエストを投げて、そこからOKであれば、204でレスポンスが返ってきて、そこからメインリクエスト(GETメソッド等)200レスポンスが返ってくる。つまりレスポンスが204と200の2個返ってくる CORSを許可するための実装には、XHR、fetch、axios、Expressを使う場合などがある 疑問 Qiitaに書きながら思っていた謎 謎1:GETメソッドでもCORSで弾かれてた点 → 調べてみると、GETメソッドでも弾かれるケースがあり、どうやら制限が厳しくなっているっぽい 謎2:OPTONSメソッドとヘッダーを加えないといけないが、GERAのソースにはOPTONSメソッドしか書いていなかくても正しくAPIが返ってきている点 → どちらかだけ書いてればOKになったみたい(ここは制限がゆるくなった?) 参考 - オリジン間リソース共有 (CORS) - HTTP | MDN - なんとなく CORS がわかる...はもう終わりにする。

Viewing all articles
Browse latest Browse all 9138

Trending Articles