CORSの根本的な理解+Laravelでの実装仕方を解説

CORSってみなつまずきますよね。
よくわからなけどとりあえずネットに書いてあることを書き写して、、
とすましてしまう人がほとんどですが、それでは困った時に使いこなせるようになりません。

そこで今回はCORSの仕組みを0から理解できるように、お伝えしていきます。

CORSってなんの略?

CORSとはCross-Origin Resource Sharingの略です。さて、今回はただ実装て着ればよい!というわけではないので、その根本部分であるオリジンとはなんなのかという部分からお伝えしていきます。

そもそもオリジンとは何か

オリジン とは、下記の組み合わせとなります。

  • ホスト(自身で取得したドメイン部)
  • スキーム(htttp,httpsといった自身でとったドメインより前の部分)
  • ポート(ドメインの後につく:80の部分)

ポートとは

インターネットで通信を行う際、上記のホストやスキームだけではなく「ポート番号」が割り振られます。
このポート番号を目印にして、アプリケーション同士の通信の判別をしていきます。
*ホストやスキームが同じでもポート番号が異なれば、パソコンは別の処理を実施します。

ポートを具体例で考えよう

より分かりやすく考えるために、建物の住所に例えてみましょう。
ホスト、スキームが建物の住所、番地だとすれば、
ポート番号はその「建物の何階にあるのか?」(一軒家ならば、通信している人はどこの部屋にいるのか?)ということになります。

CORSの説明

ブラウザが現在表示しているページ、すなわちオリジン(HTMLを読み込んだサーバのこと)以外のサーバからデータを取得する仕組みです。

これはどういうことかというと、
ブラウザには、セキュリティ強化のために同一オリジンポリシーというものが実装されています。
この同一オリジンポリシーの機能によって、あるオリジン(ページ)から他のオリジン(ページ)のリソースにアクセスできないようなっているのです。

なぜCORSがセキュリティを高めることになるのか

具体的に状況を考えてみましょう。

あなたが、お問い合わせ機能をもつホームページ(https://sample-cors-a.com)を持っているとします。
そこに対し、全然知らないページ(https://sample-cors-b.com)に、
直接あなたのページのフォームを送る機能が実装されていた場合、
あなたのサイトの受付フォームはスパムだらけになってしまう可能性があります。

ですが、仮にhttps://sample-cors-b.comが、あなたの所有であることが確認できたのであれば、 お問い合わせ数を増やすことにつながりそうです。

このような別のページ(オリジン)からリソースにアクセスすることをできるようにした仕組みが、CORSと言われているのです。

Preflight リクエストとは

自分のサイトから、別サイトに支店のデータをだしたい、といった場合などの単にデータを読み込むだけであれば、

直接クロスオリジンなリクエストを投げることは簡単です。

ですが、オリジン同士のデータの共有において、
データを削除したり、更新したりする可能性があるリクエストには、
「Preflightリクエスト」 というリクエストを事前に送信する仕組みがあります。

事前におくったPreflightリクエストに対して、

「サーバー側が問題なし」とした場合に、
実際のリクエストの送信が可能となります。

下記条件全てを満たしているのであれば、preflightリクエストは送られません。

  • HTTPメソッドがGET、HEAD、POSTのいずれかかどうか
  • HTTPヘッダにAccept, Accept-Language, Content-Language, Content-Type以外のフィールドが含まれていない
  • Content-Typeの値はapplication/x-www-form-urlencoded, multipart/form-data, text/plainのいずれかになっているかどうか

Laravelでどのように実装していくのか

さて、CORSがどのようなものかわかったところで、
具体的にLaravelでどのように実装していけば良いのかを確認していきます。

方法は二つあります。

方法1つ目: ミドルウェアを作成する

お手軽度 ☆

あまりお手軽ではありませんが、middlewareで自分でまず作ってみましょう。

まずは、middlewareを作成していきましょう。

$ php artisan make:middleware Cors
<?php

namespace App\Http\Middleware;

use Closure;

class Cors
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request)
            ->header('Access-Control-Allow-Origin', 'http://localhost:8080')
            ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
            ->header('Access-Control-Allow-Headers', 'Content-Type');
    }
}

レスポンスのHTTPヘッダーにフィールドを3つ追加しています。それぞれの役割を見て見ましょう。

Access-Control-Allow-Origin

サーバーへのアクセスを許可するオリジン(url)を記載してください。

上記例では’http://121.0.0.1:8080’のみ許可するという意味になっています。

サンプルですと、*となっていることが多いですが、この場合全てのサイトから許可するとなって、セキュリティとしてはかなり怪しいので、本番環境では自分が使用するサイトのみ入れてください。

Access-Control-Allow-Methods

許可するhttpリクエストを記載してください。

Access-Control-Allow-Headers

許可するhttpヘッダーを記載してください。

最後に、上記作成したミドルウェアをkernelに登録してください。Middleware group または apiに設定するのが一般的でしょうか。
また、実際にルーティングに設定する場合は、preflightリクエストの可能性を考えて、Route:match( ‘options’,メソッド,Cotroller@)としてください。

方法2つ目: barryvdh/laravel-cors

お手軽度 ☆ ☆ ☆

さて、上記middlewareでどんなことをすれば良いのかがわかったと思いますので、続いては、簡単に設定ができるライブラリを使った方法をお伝えします。

下記コマンドで、ライブラリを入れてください。

composer require barryvdh/laravel-cors

次に、app/Http/Kernel.phpに作成したmiddlewareを追加してください。RouuteGroupまたは、apiのどちらでもお好きな方に入れてください。

続いて、下記コマンドを打って、config/cors.phpを生成してください。

*コマンドを打ち込めば自動的に作成されます。

php artisan vendor:publish --provider="BarryvdhCorsServiceProvider"

例えば以下のようにしましょう。

<?php
return [

    'supportsCredentials' => false,
    'allowedOrigins' => [],
    'allowedOriginsPatterns' => ['@^chrome-extension://.*@'],
    'allowedHeaders' => ['*'],
    'allowedMethods' => ['*'],
    'exposedHeaders' => [],
];

supportsCredentials : クッキーやBasic認証の許可設定
allowedOrigins : 許可するドメイン
allowedHeaders : 許可するヘッダー
allowedMethods : 許可するメソッド
allowedOriginsPatterns:allowedOriginsを正規表現パターンで設定ができます。
exposedHeaders : レスポンスに含める内容を記載

CORSに対応できているかの確認

さてここまできたら、実際にcorsが適用されているのかの確認をしてきましょう。

CURLで確認するのが簡単です。

以下コマンドを打ち込んでください。

$ curl -X GET -I -H "Origin: https://sample-cors-b.com” https://sample-cors-a.com

それぞれのオプションは下記のようになっています。

-I : Headerのみ取りだして、出力
-X : メソッドを指定します
-H : ヘッダを指定します
ヘッダの Origin に送信元のURLを指定する。
(今回の場合であれば、https://sample-cors-b.com)

許可されているドメインの場合は、 200 が返ってきて、
許可されていない場合は、 403 が返ってきます。

まとめ

Laravelでapiサーバを作る際にはCORSの理解が必要不可欠です。意味もわからずなんとなく・・ではなく、何をしているのかの仕組みを理解して、サーバーの構築を行ってみてください。
laravelでのapiサーバーの作り方はこちらで紹介しています。  Laravel高速でapiサーバーを作りjsonでCRUD処理Laravel高速でapiサーバーを作りjsonでCRUD処理続きはこちら

2 COMMENTS

コメントを残す