Symfony 在用户条件下登录后重定向

Dan*_*iel 6 redirect login symfony

我的 symfony3 登录页面默认重定向到主页,如我的security.yml文件中所述。

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

有很多关于如何根据角色重定向用户的 SO 主题,文档讲述了从表单的操作字段或内重定向的内容security.yml,但不是我正在寻找的任何主题。

如何根据条件重定向?

注意:由于某些原因,我还不能使用 FOSUserBundle :-(

Nic*_*aag 6

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

那么你应该有一个扩展AbstractGuardAuthenticator类的类。

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

您需要@router通过dependencyInjection将服务传递给Authenticator 类。

假设您通过了路由器服务,您的方法将如下所示:

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;
}
Run Code Online (Sandbox Code Playgroud)


Atl*_*tli 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
Run Code Online (Sandbox Code Playgroud)

登录信息类似于:

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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)