Symfony2:ログアウト

画像 Symfony2の黄金律の1つは、コードまたはテンプレート内のリンクとパスをハードコーディングしないことです。 このルールを順守し、ルーターを介してリンクを生成することで、生活が大幅に促進されます。 しかし、私がよく観察することが1つあります。たとえば、 "/ logout"のように、ログアウトへのリンクをハードコードし続ける人がいます。問題に対する最善の解決策ではありません。



Symfony2 Securityのコンポーネント(およびバンドル)に関する小さな情報



ほとんどの開発者は、1つのプロジェクト内で複数の保護されたセクションを作成できることを知っています。 たとえば、 / secureパスを持つ一般ユーザー(登録ユーザー)用のパネルです。 また、おそらく、プロジェクトの/ adminに別の管理パネルがあり、 / apiアドレスのセクションにAPIユーザー用の別のゾーンがある場合があります。 また、保護をまったく必要としない「保護されたゾーン」を作成することができます-このアプローチは、開発者のSymfony2ツールバーで使用されます。 最終的には、これらすべてを1つの大きなゾーンに転送できます。このゾーンでは、プロジェクトの保護された部分に誰がアクセスできるかを決定するためのいくつかのオプションが実装されます。 一般に、プロジェクトを別々のゾーンに分割すると、プロジェクトがより難しくなりますが、いくつかの利点があります。



各保護ゾーンは独自のファイアウォールを呼び出し、ユーザーを認証するかどうかを決定します。 各ファイアウォールは他のファイアウォールとは別のものです。いずれかのファイアウォールで認証しても、他のファイアウォールで自動的に認証されるわけではなく、アクティブなファイアウォール(URLパターンに一致するファイアウォール)が1つしかないわけではありません。 これは、異なるファイアウォールが異なるデータベースを使用したり、異なる認証方法を使用したりできるためです(たとえば、APIではOAuthトークンを使用できますが、残りのセクションではログインフォームを使用できます)。



これは、各ファイアウォールに異なるログアウトパスがあり、それらの一部ではログアウトが存在しないことも意味します。 Security.ymlの例



#   dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false #   superadminstuff: pattern: ^/admin http_basic: provider: memory_user_provider realm: "Super Admin section!" #        main: pattern: ^/ form_login: provider: fos_userbundle csrf_provider: form.csrf_provider login_path: /login logout: true
      
      





これはsecurity.ymlの「ファイアウォール」ブロックであり、3つのファイアウォール( devsuperadminstuff 、およびmain)を定義します。 devは認証をまったく使用しません(security = false)。つまり、アクセスは全員に許可され、パス「/ js」、「/ css」などはメインファイアウォールによって制御されません。



次の一連のルールは、管理領域を保護します。 入力としてhttp_basicを使用します。つまり、ユーザー名とパスワードを指定するように求めるダイアログボックスがブラウザに表示されます(実際、プレーンテキストとして送信されるため、これはあまり安全ではありません)。 さらに、ブラウザはプロジェクトへのすべてのリクエストでユーザー名とパスワードを送信します。 Symfony2は「memory_user_provider」プロバイダーを使用してこのデータを検証できますが、そのブロックは引用しませんでしたが、通常はいくつかの標準ユーザーとそのユーザー名/パスワードを示します(データベースではなく、構成ファイルで直接)。



この場合の唯一の方法は要求の送信を停止することであるため、http-basicには実際にログアウトはありません。 この場合、通常、キャッシュをクリアするか、ブラウザを再起動するとログアウトできます。



最後のファイアウォールがメインです。 http-basicの代わりに、ログインフォームを使用します。 FOSUserBundleを使用します。FOSUserBundleには独自のログインフォームとそれを処理するメソッドがあります。そのため、開発者に必要なことは、独自に作成せずに少しカスタマイズすることです。



このファイアウォールでページを開き、以前にログインしたことがない場合、Symfony2は自動的にユーザーをログインページにリダイレクトします。ログインページはform_loginブロックのlogin_pathパラメーターで指定されます。 通常(デフォルトで)、これはアドレス/ログインのパスです(必要に応じて変更できます。必要に応じて、ルートを指定することもできます)。 ユーザーがログインするとすぐに、Symfony2はユーザーとセッション内のロールを保存し、ユーザーが次にプロンプ​​トを表示したときに、再度ログインする必要はありません。



このようなファイアウォールを終了するのは非常に簡単です-終了ページに移動する必要があります。 しかし、このページは何ですか?



上記の例では、パラメーター「logout:true」が使用されています。 このパラメーターは、form_loginブロックではなくファイアウォールブロックにあることに注意してください。 logout:trueを指定することにより、Symfony2に標準のログアウト設定を使用するように指示します。



 logout: csrf_parameter: _csrf_token csrf_token_generator: ~ csrf_token_id: logout path: /logout target: / success_handler: ~ invalidate_session: true delete_cookies: name: path: null domain: null handlers: []
      
      





ご覧のとおり、出口に沿って進むパスが示されています。 ただし、1つ奇妙な点があります。デフォルトでは、コントローラーまたはアクションが呼び出される前にログアウトリスナーが起動され、「ターゲット」パラメーターで指定されたページにリダイレクトされます。 「handlers」パラメーターで指定された独自のログアウトイベントハンドラーがあり、HTTP応答オブジェクトを返さない場合、現在のルートが呼び出されます。 つまり、デフォルトではコントローラー/アクションは呼び出されませんが、それらを指定する必要があります(つまり、Symfony2ルーターはそれについて知る必要があります)。 このため、 FOSUserBundleでは例外がスローされないため、例外をスローするという奇妙なアクションログアウトを見つけることができます。



ログアウト



それでは、出口をどうするか? まず、URLをハードコーディングしないでください。 URLの代わりにルートを使用する場合でも、構成内で変更でき、出力は機能しなくなります。 本当に価値があるのは、設定で指定されたリンクまたはルートを小枝で示すことです。 幸いなことに、SecurityBundleにはこれを行うのに役立つtwigの拡張機能があります。 これらは、logout_urlおよびlogout_path関数です。 これらの関数は、ファイアウォールID(たとえば、「main」、「dev」など)を受け取り、正しい終了アドレスを生成します。



 <a href="{{ logout_path('main') }}">Logout</a>
      
      





この場合、正しいアドレスが選択され、csrf-tokenがボーナスとして追加されます(構成で指定されている場合)。 したがって、テンプレートでページアドレスを指定する代わりに、現在使用されているファイアウォールを指定する必要があります。



確かに、テンプレートは必要以上に理解されているため、ファイアウォールの名前を手動で指定する必要があります。 ほとんどの場合、これは正常ですが、時々問題を引き起こす可能性があります(たとえば、小枝が使用されているメニューを使用する場合)。 これに関する問題を回避するために、現在のファイアウォールの名前を取得することは可能ですが、少し間違っています。



 <a href="{{ logout_path(app.security.token.providerKey) }}">Logout</a>
      
      





セキュリティコンテキストトークン内には、必要な現在のファイアウォールの名前があります。 ソリューションの「不正確さ」は、Symfonyバージョン2.6のグローバル変数app.securityがバージョン3.0で廃止され、削除されることです。 時間が経つにつれて、私は方法を生成する他の方法があると確信しています。



All Articles