schedule2020-01-23

LaravelでCSRF保護からURIを除外する

LaravelでCSRF保護からURIを除外する方法についてです。

webのCSRF保護とエラー

routes/web.phpに外部からのリクエストを想定して/some/endpointのエンドポイントを作り、リクエストを投げるとCSRF tokenについてのエラーが出る。

[2020-01-22 18:56:41] production.ERROR: EXCEPTION some/endpoint {"statuscode":500,"error_info":"Illuminate\\Session\\TokenMismatchException: CSRF token mismatch. in /var/www/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php:82

これは、デフォルトでmiddlewareにVerifyCsrfTokenが設定されているためです。 routes/api.phpにはその設定がないためリクエストが通ります。

app/Http/Kernel.php

/**
     * The application's route middleware groups.
     *
     * @var array
     */
    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',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

特定のURIのCSRF保護を除く

VerifyCsrfTokenの$except`に追加したエンドポイントはCSRF保護から除かれます。

app/Http/Middleware/VerifyCsrfToken.php

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        'some/endpoint',
        'foo/*',
    ];
}

この例では、some/endpointfoo/に続くURIがCSRF保護から除かれました。