Как проверить, зарегистрирован ли пользователь в Symfony2 внутри контроллера?

Я прочитал здесь, как проверить статус входа пользователя внутри шаблона ветки для веб-сайта на основе Symfony2. Однако мне нужно знать, как проверить, зарегистрирован ли пользователь изнутри контроллера. Я был уверен, что следующий код был прав:

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

но он всегда возвращает что-то, например. зарегистрированного пользователя или анонимного пользователя.

Любая идея? Спасибо заранее.

Ответ 1

Предупреждение: проверка только для 'IS_AUTHENTICATED_FULLY' вернет false, если пользователь выполнил вход в систему, используя функцию "Запомнить меня".

В соответствии с документацией Symfony 2 существует 3 возможности:

IS_AUTHENTICATED_ANONYMOUSLY - автоматически назначается пользователю, который в защищенной части брандмауэра сайта, но на самом деле вошел в систему. Это возможно только в том случае, если анонимный доступ разрешен.

IS_AUTHENTICATED_REMEMBERED - автоматически назначается пользователю, который был аутентифицируется через куки файл "запомнить меня".

IS_AUTHENTICATED_FULLY - автоматически назначается пользователю, который имеет предоставили свои данные для входа в течение текущего сеанса.

Эти роли представляют собой три уровня аутентификации:

Если у вас есть роль IS_AUTHENTICATED_REMEMBERED, то у вас также есть роль IS_AUTHENTICATED_ANONYMOUSLY. Если у вас есть IS_AUTHENTICATED_FULLY, тогда у вас также есть две другие роли. Другими словами, эти роли представляют собой три уровня "сила" аутентификации.

У меня возникла проблема, когда пользователи нашей системы, которые использовали функциональность "Помни меня", обрабатывались так, как если бы они вообще не вошли в систему на страницах, которые проверялись только на 'IS_AUTHENTICATED_FULLY'.

Тогда ответ должен состоять в том, чтобы потребовать, чтобы они повторно вошли в систему, если они полностью не прошли аутентификацию, или чтобы проверить запомненную роль:

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

Надеюсь, это спасет кого-то там от совершения той же самой ошибки, которую я совершил. Я использовал этот пост в качестве ссылки, когда смотрел, как проверить, был ли кто-то зарегистрирован или нет на Symfony 2.

Источник: http://symfony.com/doc/2.3/cookbook/security/remember_me.html#forcing-the-user-to-re-authenticate-before-accessing-certain-resources

Ответ 2

SecurityContext будет устаревшим в Symfony 3.0

До Symfony 2.6 вы должны использовать SecurityContext.
SecurityContext будет устаревать в Symfony 3.0 в пользу AuthorizationChecker.

Для Symfony 2.6+ и Symfony 3.0 используйте AuthorizationChecker.


Symfony 2.6 (и ниже)

// 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+ (и от Symfony 2.6 +)

security.context становится security.authorization_checker.
Теперь мы получаем наш токен от security.token_storage вместо 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

Подробнее читайте в документах: AuthorizationChecker
Как это сделать в twig?: Symfony 2: Как проверить, не зашел ли пользователь внутри шаблона?

Ответ 3

Попробуйте следующее:

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

Дополнительная информация:

"Анонимные пользователи технически аутентичны, что означает, что isAuthenticated() анонимного объекта пользователя вернет true. Чтобы проверить, действительно ли ваш пользователь аутентифицирован, проверьте IS_AUTHENTICATED_FULLY роль."

Источник: http://symfony.com/doc/current/book/security.html

Ответ 4

Если вы используете роли, вы можете проверить ROLE_USER это решение, которое я использую:

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

Ответ 5

Если вы используете аннотацию безопасности из SensioFrameworkExtraBundle, вы можете использовать несколько выражений (которые определены в \Symfony\Component\Security\Core\Authorization\ExpressionLanguageProvider):

  • @Security("is_authenticated()"): чтобы проверить, что пользователь отключен, а не анонимный
  • @Security("is_anonymous()"): чтобы проверить, является ли текущий пользователь анонимным пользователем
  • @Security("is_fully_authenticated()"): эквивалентно is_granted('IS_AUTHENTICATED_FULLY')
  • @Security("is_remember_me()"): эквивалентно is_granted('IS_AUTHENTICATED_REMEMBERED')

Ответ 6

Чтобы добавить к ответу, предоставленному Anil, в symfony3, вы можете использовать $this->getUser(), чтобы определить, вошел ли пользователь в систему, простое условие, подобное if(!$this->getUser()) {}.

Если вы посмотрите на исходный код, доступный в базовом контроллере, он точно определит то же, что и Anil.