简体   繁体   English

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

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

I set up the basic system to redirect non-login users to the login page我设置了基本系统以将非登录用户重定向到登录页面

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

Everything works perfectly, When I'm not logged in. it redirects me properly to my login page, On the other hand, when I am connected.一切正常,当我没有登录时。它会正确地将我重定向到我的登录页面,另一方面,当我连接时。 I want the user to be redirected to home instead of having an error (which I currently have).我希望将用户重定向到家而不是出现错误(我目前有)。

登录用户何时登录

I know that the error is normal but I would like a redirection I find it cleaner, a redirection with an error message would be even better.我知道错误是正常的,但我想要一个重定向,我觉得它更干净,带有错误消息的重定向会更好。

Here is my controller:这是我的 controller:

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,
    ]);
}
}

My controller is similar to the symfony documentation at: https://symfony.com/doc/current/security.html#form-login我的 controller 类似于 symfony 文档: https://symfony.com/doc/current/security.html#form-login

Add a redirect in your login method so that if the user is logged in, he will be redirected to any page you want.在您的登录方法中添加重定向,以便如果用户登录,他将被重定向到您想要的任何页面。

You can autowire use Symfony\Component\Security\Core\User\UserInterface;您可以use Symfony\Component\Security\Core\User\UserInterface; in your method to retrieve the logged in user (if its the case) without having to use TokenStorage .在您的方法中检索登录用户(如果是这种情况),而无需使用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]);
}

The issue is probably because when logging your user don't have a role.问题可能是因为在登录时您的用户没有角色。 It required to have ROLE_USER to get access to the /home page.它需要 ROLE_USER 才能访问 /home 页面。 So, to make sure that a user have a least the ROLE_USER, you should add this to your User Entity:因此,为确保用户至少拥有 ROLE_USER,您应该将其添加到您的用户实体中:

/**
 * @see UserInterface
 */
public function getRoles(): array
{
    $roles = $this->roles;
    // guarantee every user at least has ROLE_USER
    $roles[] = 'ROLE_USER';

    return array_unique($roles);
}

I had thought of this solution here but according to several articles and opinions that I put below, I am looking for a more orthodox solution and in the standards:我在这里想到了这个解决方案,但根据我在下面提出的几篇文章和意见,我正在寻找一个更正统的解决方案和标准:

"First idea that comes to mind. Well, it's kinda naive approach, but it works. Copy-paste three controllers and voilá tests just passed. It's just three pages, so it's ok, isn't it? “想到的第一个想法。嗯,这是一种幼稚的方法,但它有效。复制粘贴三个控制器,瞧,测试刚刚通过。它只有三页,所以没关系,不是吗?

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

Duplication in multiple controllers can become massive problem.多个控制器中的重复可能会成为大问题。 Just imagine the code if every action needs to do such check.如果每个动作都需要做这样的检查,想象一下代码。 For example if you want to force users to change password every month?例如,如果您想强制用户每月更改密码? On top of that if you are using FOSUserBundle (or any other external user bundle) you have to override 3rd bundle's controllers.最重要的是,如果您使用 FOSUserBundle(或任何其他外部用户捆绑包),您必须覆盖第三个捆绑包的控制器。 That's a lot of boilerplate code, so I'd rather avoid this solution.这是很多样板代码,所以我宁愿避免这种解决方案。 Don't repeat my mistakes and read StackOverflow more carefully:) "不要重蹈我的覆辙,仔细阅读 StackOverflow :)"

So here is the article, and indeed if I want to restrict for example the administration page to my role:所以这是这篇文章,事实上,如果我想将管理页面限制为我的角色:

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

I will not test if the user is admin on all pages manually?我不会手动测试用户是否在所有页面上都是管理员? I'm looking for a standard solution... but thanks for suggesting我正在寻找标准解决方案...但感谢您的建议

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM