Я прочитал здесь, как проверить статус входа пользователя внутри шаблона ветки для веб-сайта на основе Symfony2. Однако мне нужно знать, как проверить, зарегистрирован ли пользователь изнутри контроллера. Я был уверен, что следующий код был прав:
$user = $this->get('security.context')->getToken()->getUser();
но он всегда возвращает что-то, например. зарегистрированного пользователя или анонимного пользователя.
Любая идея? Спасибо заранее.
Предупреждение: проверка только для '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.
$securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED')
, поскольку роли являются иерархическими. Таким образом, наличие IS_AUTHENTICATED_FULLY
означает, что у пользователя также есть IS_AUTHENTICATED_REMEMBERED
.
Symfony 3.0
До Symfony 2.6
вы должны использовать SecurityContext
. SecurityContext
будет устаревать в Symfony 3.0
в пользу AuthorizationChecker
.
Для Symfony 2.6+
и Symfony 3.0
используйте AuthorizationChecker
.
// 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
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: Как проверить, не зашел ли пользователь внутри шаблона?
Controller
вы можете просто написать $this->isGranted($role, $obj, $errMsg)
. Функция denyAccessUnlessGranted()
функции isGranted()
являются просто ярлыками для вызова isGranted()
в сервисе security.authorization_checker
.
Попробуйте следующее:
if( $this->container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY') ){
// authenticated (NON anonymous)
}
Дополнительная информация:
"Анонимные пользователи технически аутентичны, что означает, что isAuthenticated() анонимного объекта пользователя вернет true. Чтобы проверить, действительно ли ваш пользователь аутентифицирован, проверьте IS_AUTHENTICATED_FULLY роль."
Если вы используете аннотацию безопасности из 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')
Если вы используете роли, вы можете проверить ROLE_USER
это решение, которое я использую:
if (TRUE === $this->get('security.authorization_checker')->isGranted('ROLE_USER')) {
// user is logged in
}
ROLE_USER
для всех. Не все приложения делают.
Чтобы добавить к ответу, предоставленному Anil, в symfony3, вы можете использовать $this->getUser()
, чтобы определить, вошел ли пользователь в систему, простое условие, подобное if(!$this->getUser()) {}
.
Если вы посмотрите на исходный код, доступный в базовом контроллере, он точно определит то же, что и Anil.