简体   繁体   中英

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:

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

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; in your method to retrieve the logged in user (if its the case) without having to use 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. So, to make sure that a user have a least the ROLE_USER, you should add this to your User Entity:

/**
 * @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. That's a lot of boilerplate code, so I'd rather avoid this solution. Don't repeat my mistakes and read StackOverflow more carefully:) "

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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