How to check if an user is logged in Symfony2 inside a controller?

SymfonyLoginSymfony Security

Symfony Problem Overview


I read here how to check the login status of an user by inside a twig template for a Symfony2-based website. However, I need to know how to check if the user is logged in from inside a controller. I was quite sure the the following code was right:

$user = $this->get('security.context')->getToken()->getUser();

but it always return something, e.g. a logged user or an anonymous user.

Any idea? Thanks in advance.

Symfony Solutions


Solution 1 - Symfony

Warning: Checking for 'IS_AUTHENTICATED_FULLY' alone will return false if the user has logged in using "Remember me" functionality.

According to Symfony 2 documentation, there are 3 possibilities:

> IS_AUTHENTICATED_ANONYMOUSLY - automatically assigned to a user who is > in a firewall protected part of the site but who has not actually > logged in. This is only possible if anonymous access has been allowed. > > IS_AUTHENTICATED_REMEMBERED - automatically assigned to a user who was > authenticated via a remember me cookie. > > IS_AUTHENTICATED_FULLY - automatically assigned to a user that has > provided their login details during the current session.

Those roles represent three levels of authentication:

> If you have the IS_AUTHENTICATED_REMEMBERED role, then you also have > the IS_AUTHENTICATED_ANONYMOUSLY role. If you have the > IS_AUTHENTICATED_FULLY role, then you also have the other two roles. > In other words, these roles represent three levels of increasing > "strength" of authentication.

I ran into an issue where users of our system that had used "Remember Me" functionality were being treated as if they had not logged in at all on pages that only checked for 'IS_AUTHENTICATED_FULLY'.

The answer then is to require them to re-login if they are not authenticated fully, or to check for the remembered role:

$securityContext = $this->container->get('security.authorization_checker');
if ($securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
    // authenticated REMEMBERED, FULLY will imply REMEMBERED (NON anonymous)
}

Hopefully, this will save someone out there from making the same mistake I made. I used this very post as a reference when looking up how to check if someone was logged in or not on Symfony 2.

Source: http://symfony.com/doc/2.3/cookbook/security/remember_me.html#forcing-the-user-to-re-authenticate-before-accessing-certain-resources

Solution 2 - Symfony

SecurityContext will be deprecated in Symfony 3.0

Prior to Symfony 2.6 you would use SecurityContext.
SecurityContext will be deprecated in Symfony 3.0 in favour of the AuthorizationChecker.

For Symfony 2.6+ & Symfony 3.0 use AuthorizationChecker.


Symfony 2.6 (and below)

// Get our Security Context Object - [deprecated in 3.0]
$security_context = $this->get('security.context');
# e.g: $security_context->isGranted('ROLE_ADMIN');

// Get our Token (representing the currently logged in user)
$security_token = $security_context->getToken();
# e.g: $security_token->getUser();
# e.g: $security_token->isAuthenticated();
# [Careful]             ^ "Anonymous users are technically authenticated"

// Get our user from that security_token
$user = $security_token->getUser();
# e.g: $user->getEmail(); $user->isSuperAdmin(); $user->hasRole();

// Check for Roles on the $security_context
$isRoleAdmin = $security_context->isGranted('ROLE_ADMIN');
# e.g: (bool) true/false

Symfony 3.0+ (and from Symfony 2.6+)

security.context becomes security.authorization_checker.
We now get our token from security.token_storage instead of the security.context

// [New 3.0] Get our "authorization_checker" Object
$auth_checker = $this->get('security.authorization_checker');
# e.g: $auth_checker->isGranted('ROLE_ADMIN');

// Get our Token (representing the currently logged in user)
// [New 3.0] Get the `token_storage` object (instead of calling upon `security.context`)
$token = $this->get('security.token_storage')->getToken();
# e.g: $token->getUser();
# e.g: $token->isAuthenticated();
# [Careful]            ^ "Anonymous users are technically authenticated"

// Get our user from that token
$user = $token->getUser();
# e.g (w/ FOSUserBundle): $user->getEmail(); $user->isSuperAdmin(); $user->hasRole();

// [New 3.0] Check for Roles on the $auth_checker
$isRoleAdmin = $auth_checker->isGranted('ROLE_ADMIN');
// e.g: (bool) true/false

Read more here in the docs: AuthorizationChecker
How to do this in twig?: https://stackoverflow.com/questions/9660764/symfony-2-how-do-i-check-if-a-user-is-not-logged-in-inside-a-template/23612913#23612913

Solution 3 - Symfony

Try this:

if( $this->container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY') ){
    // authenticated (NON anonymous)
}

Further information:

> "Anonymous users are technically authenticated, meaning that the > isAuthenticated() method of an anonymous user object will return true. > To check if your user is actually authenticated, check for the > IS_AUTHENTICATED_FULLY role."

Source: http://symfony.com/doc/current/book/security.html

Solution 4 - Symfony

To add to answer given by Anil, In symfony3, you can use $this->getUser() to determine if the user is logged in, a simple condition like if(!$this->getUser()) {} will do.

If you look at the source code which is available in base controller, it does the exact same thing defined by Anil.

Solution 5 - Symfony

If you are using security annotation from the SensioFrameworkExtraBundle, you can use a few expressions (that are defined in \Symfony\Component\Security\Core\Authorization\ExpressionLanguageProvider):

  • @Security("is_authenticated()"): to check that the user is authed and not anonymous
  • @Security("is_anonymous()"): to check if the current user is the anonymous user
  • @Security("is_fully_authenticated()"): equivalent to is_granted('IS_AUTHENTICATED_FULLY')
  • @Security("is_remember_me()"): equivalent to is_granted('IS_AUTHENTICATED_REMEMBERED')

Solution 6 - Symfony

If you using roles you could check for ROLE_USER that is the solution i use:

if (TRUE === $this->get('security.authorization_checker')->isGranted('ROLE_USER')) {
	// user is logged in
} 

Solution 7 - Symfony

It's good practise to extend from a baseController and implement some base functions implement a function to check if the user instance is null like this if the user form the Userinterface then there is no user logged in

/**

*/
class BaseController extends AbstractController
{

    /**
     * @return User

     */
    protected function getUser(): ?User
    {
        return parent::getUser();
    }

    /**
     * @return bool
     */
    protected function isUserLoggedIn(): bool
    {
        return $this->getUser() instanceof User;
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJeanValjeanView Question on Stackoverflow
Solution 1 - SymfonyBrysonView Answer on Stackoverflow
Solution 2 - SymfonyAnilView Answer on Stackoverflow
Solution 3 - SymfonyLorenzo MarconView Answer on Stackoverflow
Solution 4 - SymfonyIbrahim Azhar ArmarView Answer on Stackoverflow
Solution 5 - SymfonymagnetikView Answer on Stackoverflow
Solution 6 - SymfonyRedwan NassimView Answer on Stackoverflow
Solution 7 - SymfonyMike SmitView Answer on Stackoverflow