php - Symfony 4:不要重定向到 /login 来匹配路由
问题描述
我有一个有两个主要部分的 Symfony 应用程序。 /
(根目录下的所有内容 eg /userProfile
)和/api/
(/api
路由下的所有内容 eg /api/userInfo/3
)。
我正在使用 Twig 在 root 下渲染实际页面,并简单JsonResponse
地在/api
. 目前,当用户在未登录的情况下尝试访问任何页面/资源时,他们会被重定向到/login
他们请求的页面/资源。
我想为下的所有资源更改此行为/api
。我想做/api/whatever
的是返回请求的资源(如果已登录),或者如果未登录则返回 401。我想继续重定向到/login
所有其他路线。
(注意:/api
路由本身不是“RESTful”API 路由。它们是 UI 用来请求呈现各种页面所需数据的“内部”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
如果我不包含login_path
和, Symfony 会抱怨check_path
。
那么,当用户未登录(或会话已过期)时,我如何告诉 Symfony 简单地失败并返回 401,当(且仅当)他们访问下的路由时/api
?
谢谢。
解决方案
要使其正常工作,请将api
防火墙移到main
.
然后我们可以security.yaml
使用以下结构对其进行设置:
api:
pattern: ^/api
context: main
stateless: false
anonymous: true
guard:
authenticators:
- App\Security\ApiAuthenticator
provider: db_provider
我们需要的另一件事是实现AuthenticatorInterface
. 例如App\Security\ApiAuthenticator
我们只需要从接口实现以下两个方法:
start
和supports
public function start(Request $request, AuthenticationException $authException = null)
{
return new Response('', Response::HTTP_UNAUTHORIZED);
}
public function supports(Request $request)
{
return false;
}
注意:上面的实现是在 Symfony 4 (4.3) 上测试的
推荐阅读
- python - 如何使用熊猫从完整数据框中查找重复项?
- javascript - 无法从某些特定路由中隐藏某些组件
- javascript - 函数体中的 JavaScript 逗号分隔值
- javascript - 我的 POST 请求因“使用 GET/HEAD 方法的请求不能有正文”错误而失败
- ddev - 如何将 drush 8 与 Drupal 8 或 Drupal 9 一起使用?
- javascript - 正则表达式模式跳过所有其他条目
- python - Tkinter 按钮是完全白色的 Mac
- python - 如何达到满足提前停止条件的纪元数
- mariadb - Mariadb 列存储到 outfile
- image - 查找分钟的 x 和 y 坐标并将它们显示在同一个文件中