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

30

我只是希望,即使管理员用户或前台用户已经登录,仍然可以访问登录页面。

/admin/login (admin user) 

或者

/login (front end user)

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

4个回答

65

更简单的解决方法是在app/config/security.yml文件中添加以下两行:

always_use_default_target_pathdefault_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/

1
我在这里没有看到任何基于角色的决策逻辑。你能否解释一下...为什么/在哪里这个片段将ROLE_ADMIN重定向到与ROLE_USER不同的路由?你的回答有9个赞,但显然没有回答原问题。我在这里漏掉了什么吗?你必须在侦听器中根据用户的角色另外设置会话变量_security.<firewall-name>.target_path才能使其工作... - Nicolai Fröhlich
1
另一种选择是在登录表单本身中提供一个隐藏的输入字段 _target_path ... 这在管理员和用户使用相同的登录表单的情况下是不可能的。请参阅文档 - Nicolai Fröhlich
1
在default_target_path中,您也可以使用路由名称而不是路径。 - Iago
“/your/start/path/”是成功登录后您想要重定向的路径。 - Josiah
谢谢!这是文档 - Vasilii Suricov

44

使用LoginHandlers在Symfony2中重定向登录/注销

当登录成功时,您应该实现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 - Nezar Fadle
1
最佳答案。我在Symfony 3.2上尝试过,它完美地运行。顺便说一句,如果您覆盖了FOSUserBundle安全控制器,然后在代码中正确编写了authorization_checker部分,它不会识别isGranted验证,因此您无法根据角色重定向用户,但是如果您使用此答案,一切都可以完美地运行。谢谢! - Rodolfo Velasco

22

您可以覆盖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);
    }

    // ... 

3
我在这里谈论的是重写(overriding)控制器...而不是直接修改第三方代码。在下次给答案投反对票之前,请确保你真正理解了它们。请阅读文档章节"如何重写Bundle的任何部分",感谢您的阅读,祝您编码愉快! - Nicolai Fröhlich
当覆盖控制器时,您是否必须在AppKernel.php中注册“子”包? - Mr B
1
@Sid - 是的,您必须在 AppKernel.php 中注册“child”包才能覆盖“parent”包(FOSUserBundle)中的控制器。 - Nicolai Fröhlich
1
在FOSUserBundle的基于事件的重构(v2.x)之前...在版本1.x中,该包的内部流程是这样的。这是一个三年前的答案,在当时是正确的。一旦我有时间,我可以重新制作它。 - Nicolai Fröhlich
哦,好的。没注意到。谢谢。 - JohnSmith
显示剩余2条评论

3

在您添加了default_target_path的页面的控制器中进行重定向,以达到所需的方向,例如,如果您将default_target_path: /index放置在HomePageCOntroller中定义的操作index上,请转到HomePageCOntroller,使用以下代码测试当前用户是否为管理员:

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

并将他重定向到管理员空间。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接