FOSUserBundle 登录后从登录页面重定向

Posted

技术标签:

【中文标题】FOSUserBundle 登录后从登录页面重定向【英文标题】:FOSUserBundle redirect from login page after logged in 【发布时间】:2013-09-17 23:14:11 【问题描述】:

我只是希望管理员用户或前端用户即使在登录后也尝试访问登录页面

/admin/login (admin user) 

/login (front end user)

然后他们应该被重定向回他们的相关主页,如/admin/

【问题讨论】:

【参考方案1】:

更简单的解决方案是将这两行添加到您的 app/config/security.yml:

always_use_default_target_path & default_target_path,例如:

firewalls:
    main:
        pattern: ^/
        form_login:
            provider: fos_userbundle
            csrf_provider: form.csrf_provider
            login_path: /login
            check_path: /login_check
            always_use_default_target_path: false
            default_target_path:            /your/start/path/

【讨论】:

我在这里看不到任何基于角色的决策逻辑。您能否解释一下...为什么/此 sn-p 将 ROLE_ADMIN 重定向到与 ROLE_USER 不同的路线?您的回答有 9 个赞成票,但显然没有提供原始问题的答案。我在这里错过了什么吗?您必须根据用户在侦听器中的角色额外设置会话变量 _security.<firewall-name>.target_path 才能使其正常工作... 另一种方法是在登录表单本身内提供一个隐藏的输入字段_target_path ...如果管理员和用户使用相同的登录表单,这是不可能的。见doc 在default_target_path中,也可以使用路由名代替路径。 "/your/start/path/" 是登录成功后要重定向到的路径。 谢谢!这是doc【参考方案2】:

Redirecting on login/logout in Symfony2 using LoginHandlers

您应该实现AuthenticationSuccessHandlerInterface 来处理登录成功时的最后一分钟决定。

实现AuthenticationSuccessHandlerInterface:

<?php
// AcmeBundle\Security\LoginSuccessHandler.php

namespace AcmeBundle\Security;

use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Router;

class LoginSuccessHandler implements AuthenticationSuccessHandlerInterface 

    protected $router;
    protected $authorizationChecker;

    public function __construct(Router $router, AuthorizationChecker $authorizationChecker) 
        $this->router = $router;
        $this->authorizationChecker = $authorizationChecker;
    

    public function onAuthenticationSuccess(Request $request, TokenInterface $token) 

        $response = null;

        if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) 
            $response = new RedirectResponse($this->router->generate('backend'));
         else if ($this->authorizationChecker->isGranted('ROLE_USER')) 
            $response = new RedirectResponse($this->router->generate('frontend'));
        

        return $response;
    


将您的课程注册为服务:

# app/config/services.yml

services:
    authentication.handler.login_success_handler:
        class:  AcmeBundle\Security\LoginSuccessHandler
        arguments:  ['@router', '@security.authorization_checker']

在防火墙中添加对 LoginSuccessHandler 类的引用

# app/config/security.yml

firewalls:
    main:
        pattern: ^/
            form_login:
                success_handler: authentication.handler.login_success_handler     

【讨论】:

它更干净@TurdalievNursultan 最佳答案。我在 Symfony 3.2 上尝试过,效果很好。顺便说一句,如果您覆盖 FOSUserBundle 安全控制器,然后在代码中正确编码 authentication_checker 部分,则它无法识别 isGranted 验证,因此您无法根据角色重定向用户,但如果您使用此答案,一切正常。谢谢!【参考方案3】:

您可以覆盖FOSUserBundle\Controller\SecurityController,并在loginAction 的顶部添加以下代码。

use Symfony\Component\HttpFoundation\RedirectResponse;

// ...

public function loginAction(Request $request)

    $authChecker = $this->container->get('security.authorization_checker');
    $router = $this->container->get('router');

    if ($authChecker->isGranted('ROLE_ADMIN')) 
        return new RedirectResponse($router->generate('admin_home'), 307);
     

    if ($authChecker->isGranted('ROLE_USER')) 
        return new RedirectResponse($router->generate('user_home'), 307);
    

    // ... 

【讨论】:

@venimous 我说的是 overriding 控制器在这里......不是直接修改第 3 方代码。在否决答案之前...下次请确保您真正理解它们。请阅读文档章节"How to override any part of a bundle",感谢并祝您编码愉快! 当覆盖控制器时,是否必须在 AppKernel.php 中注册“子”包? @Sid - 是的,您必须使用 AppKernel.php 注册“child”捆绑包才能覆盖“parent 中的控制器" 捆绑 (FOSUserBundle)。 为什么这是公认的答案?成功登录根本不来这里。如果您查看原始文件 (\FOS\UserBundle\Controller\SecurityController::loginAction),您会发现它只处理登录屏幕渲染。正确的解决方案是使用 LoginHandlers,见下文。 在 FOSUserBundle 的基于事件的重构 (v2.x) ... 在版本 1.x 中,bundle 的内部流程是这样的。这是一个 3 岁的答案,当时是正确的。一旦我有时间,我可以重做它。【参考方案4】:

只需在你在default_target_path中添加的页面的控制器中重定向到想要的方向,例如,如果你把default_target_path: /index和index是在HomePageCOntroller中定义的一个动作,去HomePageCOntroller,测试当前用户是否为管理员:

if (($this->container->get('security.context')->isGranted('ROLE_ADMIN'))) 

然后将他重定向到管理空间。

【讨论】:

以上是关于FOSUserBundle 登录后从登录页面重定向的主要内容,如果未能解决你的问题,请参考以下文章

如果用户已登录,则重定向

Symfony - 如何将用户重定向到登录后访问的最后一个页面?

使用 FOSUserBundle 自动登录 Symfony2 [重复]

登录 ios swift 后从 wkwebview 获取令牌

Symfony FOSUserBundle 持久化 sf_redirect

httpclient302重定向怎么做