codeception functional Авторизация (symfony) через loginUser() не работает после первого запроса в функциональных тестах
Primary tabs
Проблема
Решение через loginUser() для программного логина пользователя, почему-то не работает у нас (symfony 7) в ситуации, когда в цепочке более двух тестов, например :
/** * @before authAsSimpleUserVasya // первая авторизация этот метода успешно создает статью */ public function testPostCreatingBySimpleUserVasya(FunctionalTester $I) { $client = $this->client; $client->request( 'POST', '/api/' . $this->getApiVersion() . '/post/new', // ......... } /** Зависим от метода создания статьи, который перед собой проводит авторизацию и все работет нормально * @before testPostCreatingBySimpleUserVasya * @before authAsAdmin // метода ниже не сработает -- даже если авторизуемся еще раз */ public function canEditAndDeleteByAdminArticleCreatedByOtherSimpleUser(FunctionalTester $I) { $client = $this->client; $client->request( // получаем ошибку 'PUT', '/api/' . $this->getApiVersion() . '/post/edit/' . $this->postId, // ....................... } }
- в нашем случае второй метода в цепоке (зависящий от первого через @before) не проходит проверку на роль IS_GRANTED (symfony) (напр. как в примерах кода тут)
Причина проблемы, почему пропадает авторизация
After making a request, subsequent requests will make the client reboot the kernel.
- то есть ядро перезагружается на каждый запрос (для файевроволов без состояния), и особенность тут в том, что оно перезагружается не после запроса, а перед выполнением следующего запроса - внутри $client->request(), именно поэтому просто "залогиниться" перед каждым запросом нельзя, т.к. симфони отслеживает, именно факт предыдущего запроса и тупо пересоздает ядро, что не делает повторную авторизацию перед вызовом метода запроса действенной.
Ключевые слова по теме (поисковые запросы):
symfony loginUser fail auth after one request
Возможно связанные темы
- KernelBrowser::loginUser does not work when called multiple times https://github.com/symfony/symfony/issue...
- KernelBrowser reinitializes TokenStorage on subesequent Request calls https://github.com/symfony/symfony/issue...
- Multiple Requests in One Test Несколько запросов в тестах (официальная документация): https://symfony.com/doc/current/testing....
Возможные решения
- Применять способ (если он там есть, надо вникать): https://symfony.com/doc/current/testing....
- Использовать костыль с перезагрузкой ядра, чтобы для второго запроса оно было "как для первого"
- Log in to post comments
- 1039 reads
vedro-compota
Fri, 04/05/2024 - 01:01
Permalink
где происходит проверка IS_GRANTED
Вот тут: vendor/symfony/security-core/Authorization/AuthorizationChecker.php
_____________
матфак вгу и остальная классика =)
vedro-compota
Fri, 04/05/2024 - 01:23
Permalink
Перезагрузка ядра
Функция перезагрузи это
Дла поиска:
_____________
матфак вгу и остальная классика =)
vedro-compota
Fri, 04/05/2024 - 02:53
Permalink
Возможное решение: все запросы как "первые"
Вариант с пересозданием (перелогином) каждвый раз перед вызовом с подходом:
Как предлагают тут https://github.com/symfony/symfony/issue...
Другое дело, что что если унаследовать Cest-класс от WebTestCase - начнет запускаться куча публичных методов в родителях, а это не то, что нам нужно)
Поэтому можно просто написать отдельный класс-наследние, который будет отдавать клиент с залогиненным пользователем:
-- просто получайте заново клиент перед каждым запросом и stateless: true файервол начнет пропускать не только первый запрос
Если в тестах вам нужно в тестах получать исключения, то выключить их перехват клиентом:
_____________
матфак вгу и остальная классика =)
vedro-compota
Mon, 05/12/2025 - 23:18
Permalink
Исходный план, актуальное
Исходный план, актуальное решение см. в основном тексте выше.
План поиска причины проблемы
_____________
матфак вгу и остальная классика =)