首页 > 解决方案 > Symfony 安全防火墙 JSON 响应

问题描述

用户可以通过 Web 表单登录,然后使用 javascript 客户端访问 api。如果用户没有登录 api 应该返回一个带有 403 错误的 json 响应,站点上的任何其他页面应该继续重定向到登录页面。

存在以下防火墙:

firewalls:   
    main:
        pattern: ^/
        form_login:
            provider: fos_userbundle
            csrf_token_generator: security.csrf.token_manager
        logout:       true
        anonymous:    true
access_control:
    - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/api/, role: ROLE_USER }

登录表单正常工作并且 /api/ 路由是安全的。

如果 javascript 客户端曾经访问过 /api/* 并且用户没有登录,他们应该会收到 403 json 响应,目前他们会收到 302 重定向到 /login 页面。用户可能未登录,因为会话可能已过期。

当用户没有为 /api/ 路由登录时,如何返回 JSON 响应?

我尝试创建各种事件侦听器,但找不到正确的事件;以下仅触发失败的登录表单事件。

App\EventListener\SecurityListener:
    tags:
        - { name: kernel.event_listener, event: security.authentication.failure, method: onFailure }

我还可以检查每个控制器方法! isGranted(ROLE_USER)并返回JsonResponse(message: "please login", status: 403),但这不是非常理想,并且会导致大量重复代码,必须有一个更简单的解决方案。

javascript 客户端将始终发送标头Content-Type: application/json

标签: symfonysymfony4symfony-security

解决方案


您可以创建自定义处理程序和身份验证器:

form_login:
    csrf_token_generator: security.csrf.token_manager
    provider:             fos_userbundle
    login_path:           /login
    check_path:           /login_check
    success_handler:      'your_custom_login_success_handler'
    failure_handler:      'your_custom_login_failure_handler'
    guard:
        authenticators:
            - App\Security\TokenAuthenticator

推荐阅读