Symfony 登录后根据用户条件进行重定向

7

默认情况下,我的Symfony3登录页面将重定向到主页,如我的security.yml文件所述。

然而,如果用户还没有填写个人资料,我希望它可以重定向到我的“编辑个人资料”页面。在任何其他表单中,我都会在控制器内完成此操作,但由于登录表单中没有$form->handleRequest($user),因此我没有一个$user变量来进行测试。

有很多SO主题关于如何基于角色重定向用户,并且文档介绍了从表单的操作字段或security.yml中重定向,但都不是我要找的。

如何根据条件进行重定向?

NB: 由于某些原因,我现在不能使用FOSUserBundle:-(


您可以使用自定义输入在表单内部进行重定向,例如:http://symfony.com/doc/current/security/form_login.html - davidbonachera
1
这是我刚才给你的完全相同的链接... - Dan Chaltiel
糟糕… 一个解决方法可能是使用会话/cookie,如果为空,则重定向。http://symfony.com/doc/current/components/http_foundation.html#setting-cookies / http://api.symfony.com/3.2/Symfony/Component/HttpFoundation/Cookie.html - davidbonachera
在这里我找到了我需要的内容:https://dev59.com/GGgu5IYBdhLWcg3wMkUm - Darius.V
2个回答

7

我假设你正在使用Guard身份验证系统。( http://symfony.com/doc/current/security/guard_authentication.html )

然后,你应该有一个类扩展了AbstractGuardAuthenticator类。

在那个类中,有一个叫做onAuthenticationSuccess的方法,在这里你可以放一些重定向请求的逻辑。 如果你在这里返回null,它将继续使用在security.yml中配置的路由。

你需要通过依赖注入将@router服务传递给Authenticator类。

假设你传递了router服务,你的方法会像这样:

public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
    /** @var User $user */
    $user = $token->getUser();

    if ($user->hasCompleteProfile() == false) {
        $url = $this->router->generate('edit_profile');

        return new RedirectResponse($url);
    }

    // Continue with default behaviour
    return null;
}

实际上,我使用了一个简单的注册表单和一个传统的登录表单。我会研究Guard身份验证系统,但是我正在构建的网站不需要非常严格的安全性,所以可能有些过度设计了... - Dan Chaltiel
1
如果在我的情况下没有扩展AbstractGuardAuthenticator——我在项目中找不到这样的东西怎么办?如果我不想要2个重定向,因为它们会减慢页面速度。那么重构以使用AbstractGuardAuthenticator的唯一方法是什么?还是有其他的方法吗? - Darius.V

5
如果其他方法都失败了(或者处理起来太困难),你可以简单地引入一个中介路由并在其中执行逻辑。
也就是说,创建一个仅用于基于所需逻辑重定向用户的操作,并将其作为security.yml防火墙中的目标路径。
security:
    firewalls:
        main:
            pattern: ^/
            anonymous: ~
            form_login: 
                login_path: login
                check_path: login
                default_target_path: login_success
                always_use_default_target_path: true
            logout:
                path: logout

登录的方式可能是这样的:

class AuthenticationController extends Controller
{
    /**
     * @Route("/login", name="login")
     * @Route("/logout", name="logout")
     */
    public function loginAction(Request $request)
    {
        // Standard login stuff here
    }

    /**
     * @Route("/login_success", name="login_success")
     */
    public function postLoginRedirectAction()
    {
        if (/* user needs to see location A */) {
            return $this->redirectToRoute("location_a");
        } else if (/* user needs to see location B */) {
            return $this->redirectToRoute("location_b");
        } else {
            return $this->redirectToRoute("index");
        }
    }
}

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