Перехват «Отсутствует или неправильный тип файлов cookie CSRF». исключение

#php #cakephp #cakephp-4.x

#php #cakephp #cakephp-4.x

Вопрос:

Я знаю, почему возникает это исключение, это не проблема, но я не способен перехватить это исключение.

Это исключение выдается в CORE/src/Http/Middleware/CsrfProtectionMiddleware.php строке # 286:

 if (!$cookie || !is_string($cookie)) {
   throw new InvalidCsrfTokenException(__d('cake', 'Missing or incorrect CSRF cookie type.'));
}
  

Когда я проверяю длинный список стека в окне ошибки CakePHP, мне становится ясно, что я не могу начать изменять основные файлы, так как при следующем обновлении / обновлении CakePHP мои изменения будут потеряны.

Единственный скрипт, который я могу изменить и который должен быть легко обработан, это webroot/index.php . Он также упоминается в стеке вызовов в первой позиции:

CakeHttpServer->запустить ROOT/webroot/index.php:50

И здесь я застрял. Что я когда-либо пробовал:

  • try/catch ( Exception )
  • try/catch ( CakeHttpExceptionInvalidCsrfTokenException )
  • Использование set_exception_handler()

ничего не помогает, это означает, что я всегда получаю окно с ошибкой ниже. В этом окне слева вы можете увидеть длинный стек вызовов скриптов, которые вызываются до тех пор, пока не будет выдано исключение. И это даже не все сценарии. Так что это действительно вложенный.

Мой вопрос:

Как я могу поймать это исключение в самом верхнем PHP-скрипте webroot/index.php — под этим скриптом находятся еще 16 сценариев, вызываемых до тех пор, пока не будет выдано исключение. Я не хочу изменять файлы ядра CakePHP.

Я использую CakePHP 4.1.4

введите описание изображения здесь

Ответ №1:

Вы не можете перехватить это исключение index.php , поскольку оно уже перехватывается промежуточным программным обеспечением обработчика ошибок, которое представляет вам этот приятный экран ошибки, который, однако, вы увидите только в режиме отладки, если это вас беспокоит.

Вашим первым шансом перехватить это исключение будет пользовательское промежуточное программное обеспечение, которое вам нужно будет поместить между промежуточным программным обеспечением обработчика ошибок и промежуточным программным обеспечением защиты CSRF, что-то вроде этого:

 // in src/Application.php

public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
{
    $middlewareQueue
        ->add(new ErrorHandlerMiddleware(Configure::read('Error')))

        // ...

        ->add(function (
            PsrHttpMessageServerRequestInterface $request,
            PsrHttpServerRequestHandlerInterface $handler
        ) {
            try {
                // continue with the next middleware
                return $handler->handle($request);
            } catch (CakeHttpExceptionInvalidCsrfTokenException $exception) {
                // handle the catched exception
                $response = new CakeHttpResponse();

                return $response->withStringBody('Oh noes, CSRF error!');
            }
        })

        // ...
        
        ->add(new CsrfProtectionMiddleware([
            'httponly' => true,
        ]));

    return $middlewareQueue;
}
  

Комментарии:

1. Я так благодарен, что вы мне помогли! Я не боюсь сообщения об ошибке. Проблема заключается в следующем : если у пользователя в браузере открыта вкладка страницы входа в систему несколько дней, то срок действия файла cookie истекает, и это приводит к этому исключению. Я не могу сказать пользователю, что он должен нажать кнопку «Назад», удалить все файлы cookie и перезагрузить страницу. Это смешно. Когда приложение теперь улавливает это исключение, программа может выполнить все шаги для пользователя / клиента. Тем не менее, я рассматриваю это как проблему дизайна, и я не верю, что только у моих клиентов есть эта проблема.