GraphQL実装中にCORSではまった最近、個人開発でサーバとクライアントを分離したアプリケーションの実装をしています。構成は、RailsでAPIサーバを実装し、クライアントのVue.jsからGraphQLを介してデータのやり取りをしています。静的ホスティングサイトから配信されたVueアプリから、RailsのAPIサーバにアクセスする際に、同一オリジンポリシーとCORSの存在を知らずにはまってしまったので、振り返りを兼ねてまとめておきます。前半部では、同一オリジンポリシーやCORSの概念についてまとめ、後半部では、その具体的な実装についてみていきます。対象者サーバとクライアントを分離したアプリを開発中の方オリジン(源泉)オリジン(源泉)とは、以下の規則に則ってURIをまとめたものです。ブラウザによって、しばしば特権の範囲として用いられます。ある二つのURIが、同一スキーム、同一ホストおよび同一ポートを持つ場合、同一オリジンです。同一オリジンポリシーとは、ブラウザ側に備わっている仕組みで、あるオリジンから読み込まれた文章やスクリプトについて、そのリソースから他のオリジンにアクセスできないように制限するものです。制限をかけることで、リソースを、悪意を起こしかねないリソースから分離することを目的としています。要するに、セキュリティ上、リソースを外部の干渉から防ごうとするものです。クロスオリジン通信クロスオリジン通信とは、ブラウザがリソースを取得したオリジンとは別のオリジンから、データを取得する仕組みのことです。XMLHttpRequestは、JavaScriptを使用してHTTP通信を行うためのAPIです。Level2が実装されています。APIと呼ばれる新規格も登場しました。これらによって、JavaScriptを介したクロスオリジン通信が可能となりました。XHRがクロスオリジン通信を許容したことにより、クロスオリジン通信によるCSRF攻撃が可能となりました。実装の際には気をつけた方が良さそうです。Sharing)は、あるオリジン上で動いているアプリケーションが、別のオリジンの上で動いているアプリケーション上のリソースに、アクセスできるようにする仕組みです。異なるオリジン間のアクセス制限を解除するために、OriginやAccess-Control-Allow-Originヘッダを使用します。具体的に次の節で見てみましょう。APIサーバからのレスポンスをブラウザが受け取ってくれませんでした。次のようなエラーログがブラウザのコンソール上で出力されます。disabled.開発段階なのでlocalhostですが、それぞれポート番号が異なっているので、別のオリジンとみなされます。今後、本番環境でも、ホスティングとAPIサーバを分離する予定のため、CORSに対応する必要があります。エラーログにも記載してあるように、サーバ側で、異なるオリジンであるlocalhost:3000だけから、アクセスを許容できるようにAccess-Control-Allow-Originで指定してあげれば良さそうです。http://localhost:8080を含めてあげることで、ブラウザ側は、このリソースからのアクセスを許されたオリジンであると判別し、同一オリジンポリシーによる制約を解除します。*をヘッダに含めてあげれば良さそうです。RailsにおけるCORS対応Rails側のAPIサーバ側で、CORSに対応していなかったためブラウザ側で受信を拒絶されていたようです。rack-coresを使うと、簡単にCORS対応が可能になります。installをします。'rack-cors'次に、config/initializers/cors.rbのコメント部分をコメントアウトします。endendoriginsのところで、許容するオリジンを指定してあげます。これだけで、APIサーバ側でCORSの設定ができます。実際に返されたレスポンスヘッダを確認してみます。chunkedレスポンスヘッダの3行目に、Access-Control-Allow-Originが含まれているのがみて取れます。これで、ブラウザ側が、アクセスが許容されたリソースに対するレスポンスだと判断し、制限されることはなくなりました。まとめオリジンやオリジン間リソース共有といった、Webの根幹をなす概念についてまとめてみました。ハマりポイントの解決法だけではなく、その技術の根底にある仕組みや概念を深掘りすることで、自分の中でも深い理解ができた気がします。