here Symfony2ベースのWebサイトのtwigテンプレート内でユーザーのログインステータスを確認する方法を読みました。ただし、ユーザーがコントローラー内部からログインしているかどうかを確認する方法を知る必要があります。次のコードが正しいと確信しました。
$user = $this->get('security.context')->getToken()->getUser();
しかし、常に何かを返します。ログに記録されたユーザーまたは匿名ユーザー。
何か案が?前もって感謝します。
警告:ユーザーが「Remember me」機能を使用してログインしている場合、'IS_AUTHENTICATED_FULLY'
のみをチェックするとfalseが返されます。
Symfony 2のドキュメントによると、3つの可能性があります。
IS_AUTHENTICATED_ANONYMOUSLY-サイトのファイアウォールで保護された部分にいるが実際にはログインしていないユーザーに自動的に割り当てられます。これは匿名アクセスの場合のみ可能です許可されました。
IS_AUTHENTICATED_REMEMBERED-remember me cookieを介して認証されたユーザーに自動的に割り当てられます。
IS_AUTHENTICATED_FULLY-現在のセッション中にログイン詳細を提供したユーザーに自動的に割り当てられます。
これらの役割は、3つの認証レベルを表します。
IS_AUTHENTICATED_REMEMBERED
ロールを持っている場合は、IS_AUTHENTICATED_ANONYMOUSLY
ロールも持っています。IS_AUTHENTICATED_FULLY
ロールを持っている場合、他の2つのロールも持っています。つまり、これらの役割は、認証の「強度」を高める3つのレベルを表しています。
「Remember Me」機能を使用していたシステムのユーザーが、'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に誰かがログインしているかどうかを確認する方法を調べるとき、この投稿を参考として使用しました。
Symfony 3.0
で非推奨になりますSymfony 2.6
の前に、SecurityContext
を使用します。SecurityContext
は、 AuthorizationChecker
の代わりにSymfony 3.0
で非推奨になります。
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:ユーザーがテンプレート内にログインしていないかどうかを確認するにはどうすればよいですか?
これを試して:
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
}
symfonyのAnilの回答に追加するには、$this->getUser()
を使用して、ユーザーがログインしているかどうかを判断します。if(!$this->getUser()) {}
のような単純な条件でできます。
ベースコントローラーで利用可能なソースコードを見ると、Anyで定義されているものとまったく同じことが行われます。