CakePHP4でのcsrf対策の試行錯誤

久しぶりにプログラミング。
AJAX通信の部分など、特定のルートだけCSRFを除外したい!という場合の処理で苦労したので、メモです。バージョン違いなどで、いろんな情報が出てきます。
以下、cakephp4.0.8 で、うまくいく場合です。

// config/routes.php

$routes->scope('/', function (RouteBuilder $builder) {
    // Register scoped middleware for in scopes.
    // 以下の3行をコメントアウト
    // $builder->registerMiddleware('csrf', new CsrfProtectionMiddleware([
    //     'httpOnly' => true,
    // ]));

    /*
     * Apply a middleware to the current route scope.
     * Requires middleware to be registered through `Application::routes()` with `registerMiddleware()`
     */
    // 以下の1行をコメントアウト
    // $builder->applyMiddleware('csrf');
    ....
}

上記で一旦、CSRFのミドルウエアをここでは適用せずに、以下のところで適用させるようにします。

public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
    {
        // 以下、$csrfを定義、除外したいコントローラー名、アクション名を記載します
        $csrf = new CsrfProtectionMiddleware(['httpOnly'=>true]);
        $csrf->whitelistCallback(function ($request) {
            $controller = $request->getParam('controller');
            $action = $request->getParam('action');
            if (strcmp($controller,'コントローラー名') == 0 && strcmp($action,'アクション名') == 0) {
                return true;
            }
            return false;
        });

       $middlewareQueue
            // Catch any exceptions in the lower layers,
            // and make an error page/response
            ->add(new ErrorHandlerMiddleware(Configure::read('Error')))

            // Handle plugin/theme assets like CakePHP normally does.
            ->add(new AssetMiddleware([
                'cacheTime' => Configure::read('Asset.cacheTime'),
            ]))

            // Add routing middleware.
            // If you have a large number of routes connected, turning on routes
            // caching in production could improve performance. For that when
            // creating the middleware instance specify the cache config name by
            // using it's second constructor argument:
            // `new RoutingMiddleware($this, '_cake_routes_')`
            ->add(new RoutingMiddleware($this))
            // この位置に$csrfを追加します
            ->add($csrf);

これで、うまくいきます

コメント

タイトルとURLをコピーしました