У меня есть приложение Symfony, которое имеет два основных раздела. /
(все под root, например, /userProfile
) и /api/
(все по маршруту /api
, например, /api/userInfo/3
).
Я использую Twig для рендеринга реальных страниц под root, и простой JsonResponse
для рендеринга всего под /api
. В настоящее время, когда пользователь пытается получить доступ к любой странице / ресурсу, когда он не вошел в систему, он перенаправляется на /login
, а затем на запрашиваемую страницу / ресурс.
Я бы хотел изменить это поведение для всех ресурсов в /api
. /api/whatever
я бы хотел либо вернуть запрошенный ресурс (если он вошел в систему), либо вернуть 401, если он не вошел в систему. Я хотел бы продолжить перенаправление на /login
для всех других маршрутов.
(ПРИМЕЧАНИЕ. /api
маршруты не являются API-маршрутами "RESTful" per ce. Это "внутренние" маршруты API, которые пользовательский интерфейс использует для запроса данных, необходимых для визуализации различных страниц. Поэтому можно предположить, что пользователь мог бы войти через обычную форму входа до того, как его клиент запросит один из этих маршрутов.)
Вот мой security.yaml
:
security:
providers:
db_provider:
id: database_user_provider
encoders:
App\Utility\Security\DatabaseUser: bcrypt
access_decision_manager:
strategy: unanimous
allow_if_all_abstain: false
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
context: main
form_login:
provider: db_provider
login_path: login
check_path: process_login
default_target_path: manage
use_referer: true
failure_handler: App\Utility\Security\AuthenticationFailureHandler
user_checker: App\Utility\Security\UserChecker
anonymous: ~
logout:
path: logout
target: login
access_denied_handler: App\Utility\Security\AccessDeniedHandler #Turn this off in dev.
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/forgot, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/%app.locales%, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, roles: ROLE_USER }
Я попытался добавить новый контекст брандмауэра api
:
api:
pattern: ^/api
context: main
# If I don't include this (from "main" firewall), I get an error stating no UserAuthenticationListener has been provided for secuirty.firewall.api.
form_login:
provider: db_provider
login_path: login
check_path: process_login
use_referer: true
failure_handler: App\Utility\Security\AuthenticationFailureHandler
Symfony жалуется, если я не включаю login_path
и check_path
.
Итак, как мне сказать Symfony просто завершить работу с ошибкой и вернуть 401, когда пользователь не вошел в систему (или сеанс истек), когда (и только когда) он обращается к маршруту в /api
?
Спасибо.