Laravel 初心者的 API Routes うまくいかない時に

この記事は私が Laravel でアプリケーションを作り始めたときにいきなり躓きすぐさま解決したけれど、なんらかのバッドノウハウで回避しちゃってる方に贈ります。

※この記事は Laravel 6.0 を前提としています。

API のルーティングであなたはこんな経験はありませんか?

  1. rotes/api.php にルートを追加したのに呼び出せない(404になる)。
  2. REST API を外部から POST で呼び出したときに「419 Page Expired」というエラーが帰ってくる。

2については、調べてみるとどうやらリクエストに CSRFトークンが含まれていないといけないエラーである模様。結果、POST をあきらめて GET にしてみると、URL が長くなりすぎてエラーとなり、袋小路に迷い込んだ気分。

これは、私が Laravel で実際のアプリケーションを作り出して1日目に経験したことです。
ググって Stack Overlow を次々読むという不毛な作業をしたりもしたわけですけれど、あなたはそんなことをする必要はありません。

結論

rotes/api.php に追加したルートは URL に /api を追加したら呼び出せますし、 CSRF のチェックも回避できます。

もちろん、POSTということは何らかのデータを送信したいわけで、何のチェックもなくどこからもデータ受け入れ放題とはいきません。
送信元 IP アドレスをチェックする、HTTPヘッダに特定のフィールドを含ませチェックする、など middleware を追加して不正アクセス対策を実施ください。

ほんとうにもう以上なんですが、余談的にどうして api では CSRF が回避されるのか見てみましょう。

余談

Web Routes

rotes/web.php には、このように書かれています。

These routes are loaded by the RouteServiceProvider within a group which contains the “web” middleware group.

Web ルートは “web” ミドルウェアグループに属します。
ミドルウェアグループ は app/Http/Kernel.php に、以下のように定義されています。

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    'api' => [
        'throttle:60,1',
        'bindings',
    ],
];

web グループの中に VerifyCsrfToken::class がありますね。
この指定があるため、 rotes/web.php に追加したルートではデフォルトで CSRF のチェックが有効になります。

API Routes

そのすぐ下に API のミドルウェアグループがありますが・・・throttle・・・これは何でしょうね?
以下のURLに詳細が書かれています。
Laravel 6.x ルーティング レート制限

throttleミドルウェアは分数と、その時間内に許す最大リクエスト数の、2引数を取ります。

つまり、'throttle:60,1',という記述は、1分間に60回のアクセスが許されるということです。
これがデフォルトになっています。

もうひとつの bindings ・・・これもちょっと意味が分かりません。
web ルートの方にも SubstituteBindings というクラスがありますが、関係あるんでしょうか。

いろいろ検索した結果、以下のような記述がありました。

Once this route middleware has been registered, you should add it to the api middleware group:

https://laravel.com/docs/5.3/upgrade

1回登録したら次からは名前だけで OK と言いたいのでしょうか。
じゃぁ、throttle は引数まで引き連れて、こんなところで何してるんでしょうか。
そんなことはどうでもよくて、bindings は SubstituteBindings::class な模様。
そしてこの middleware は何をしてくれるのか。

ソースを見ても何も書いておらずここで力尽きたので、「WebルートとAPIルートでは常に使うんだな」と理解することにしました。
このミドルウェアが実現している  Route Model Binding は以下のページが詳しいです。

初めてのLARAVEL 5.6 : (32) ROUTE MODEL BINDING

関連記事

関連記事が見つかりませんでした。