如果登录用户访问 /login: access_control 角色则重定向

Redirect if a logged in user accesses /login: access_control roles

我设置了基本系统,将非登录用户重定向到登录页面

// security.yaml
main:
  lazy: true
  provider: app_user_provider

  form_login:
    # "login" is the name of the route created previously
    login_path: login
    check_path: login

[...]

  access_control:
  - { path: ^/home, roles: ROLE_USER }
  - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }

一切正常!当我没有登录时,它会正确地将我重定向到我的登录页面。 另一方面,当我连接时,我希望用户被重定向到主页而不是出现错误(我目前有)。

我知道错误是正常的,但我想要一个重定向,我发现它更清晰,带有错误消息的重定向会更好。

这是我的控制器:

class LoginController extends AbstractController
{
  #[Route('/login', name: 'login')]
public function index(AuthenticationUtils $authenticationUtils): Response
{

    // get the login error if there is one
    $error = $authenticationUtils->getLastAuthenticationError();

    // last username entered by the user
    $lastUsername = $authenticationUtils->getLastUsername();

    return $this->render('login/index.html.twig', [
        'last_username' => $lastUsername,
        'error'         => $error,
    ]);
}
}

我的控制器与位于以下位置的 symfony 文档类似: https://symfony.com/doc/current/security.html#form-login

在您的登录方法中添加一个重定向,这样如果用户已登录,他将被重定向到您想要的任何页面。

您可以在您的方法中自动装配 use Symfony\Component\Security\Core\User\UserInterface; 来检索登录用户(如果是这样的话),而不必使用 TokenStorage.

/**
 * @Route("/login", name="login")
 */
public function login(AuthenticationUtils $authenticationUtils, UserInterface $user = null): Response
{
    if($user !== null){
        $this->redirectToRoute('home');
    }

    // get the login error if there is one
    $error = $authenticationUtils->getLastAuthenticationError();
    // last username entered by the user
    $lastUsername = $authenticationUtils->getLastUsername();

    return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}

我在这里想到了这个解决方案,但根据我在下面发表的几篇文章和意见,我正在寻找一个更正统的解决方案和标准:

“第一个想到的想法。好吧,这有点天真,但它有效。Copy-paste 三个控制器和 voilá 测试刚刚通过。它只有三页,所以没关系,不是吗? ?

class SomeController extends BaseController
{
  public function someAction()
  {
    if ($this->isUserLogged()) {
        return $this->redirectToRoute('somewhere');
    }
    // do default action
  }
}

多个控制器中的重复会成为一个大问题。想象一下如果每个动作都需要做这样的检查的代码。例如,如果你想强制用户每月更改密码?最重要的是,如果您使用 FOSUserBundle(或任何其他外部用户包),您必须覆盖第三个包的控制器。这是很多样板代码,所以我宁愿避免这种解决方案。不要重蹈我的覆辙,更仔细地阅读 Whosebug :) "

这是这篇文章,事实上,如果我想将管理页面限制为我的角色:

# - { path: ^/admin, roles: ROLE_ADMIN }

” 我不会手动测试用户是否在所有页面上都是管理员?我正在寻找标准解决方案...但感谢您的建议