0

リクエストカーネルイベントリスナーでセッションを設定し、次のlast_seenようにセッション変数を更新します。

class RequestListener
{
    public $session;

    public function __construct( Session $session ) {
        //leave blank
        $this->session=$session;
    }

    public function onKernelRequest( GetResponseEvent $event ) {
        if ( HttpKernel::MASTER_REQUEST != $event->getRequestType() ) {
            // don't do anything if it's not the master request
            return;
        }
        else {

            $session      = $this->session;
            $current_time = time();

            //if they're logged in and it hasn't been more than an hour since their last request
            if ( $session->get( 'auth' ) ) {
                if ( ( (int) $session->get( 'last_seen' ) ) > ( $current_time - 10 ) ) {//timeout: half hour (temporarily changed to ten seconds)
                    //regenerate session ID:
                    $session->migrate();
                }
                else {
                    //destroy session
                    $session->invalidate();//shortcut for clear() & then migrate()

                    //set session variable to acknowledge timeout
                    $session->getFlashBag()->add( 'info', 'You were automatically logged out due to inactivity' );
                }
                $session->set( 'last_seen', $current_time );
            }
            else {
                $session->set( 'last_seen', $current_time );
            }
        }
    }
}

このコードは、すべてのリクエストに対して実行されます。ご覧のとおり、flashbag info flashメッセージはholdYou were automatically logged out due to inactivityに設定されていますが、これは表示されません。


私の小枝テンプレート:

他の状況で他のフラッシュが見られるので、これには何の問題もないはずです。

{# START info messages #}
{% set info_messages = app.session.flashbag.get('info') %}
{% if info_messages is defined and info_messages is not empty%}
    <div class="row alert alert-info alert-block">
        <ul>
            {% for info_message in info_messages %}
            <li>{{info_message | raw}}</li>
            {% endfor %}
        </ul>
    </div>
{% endif %}
{# END info messages #}

したがって、私がテストしてきたフローは次のとおりです。

  1. ユーザーがログインページにアクセスします
  2. ログインフォームの送信(ログインルートを更新します)
  3. ログインは成功したと見なされ、別のページにリダイレクトされます(たとえばページB)
  4. 10秒待ってから更新します
  5. カーネルイベントはセッションをクリアし、アイテムをフラッシュバッグに追加する必要があります
  6. ページBのルートのコントローラーに到達すると、セッションをチェックしてユーザーがログインしているかどうかを確認し、ログインしていないためにログインページにリダイレクトします。
  7. ログインページは小枝テンプレートをレンダリングするだけで、フラッシュは表示されません

これは、ドキュメントで簡単に説明されているフラッシュメッセージの自動有効期限と関係がありますか?

これは単純なセッションの問題であり、リダイレクトや自動有効期限の影響を受けている可能性があります。


編集

また、onKernelRequest関数を変更して、実際にすべてのリクエストに対してセッション処理コードを実行するようにしました(MASTER_REQUESTチェックを削除)


編集2

#symfony IRCチャネルで提案されているように、リスナーとコントローラーの代わりに、テンプレートの$session->setFlash('info', '...message...')代わりに使用してみましたが、それでもうまくいきません。$session->getFlashBag()->add(...)app.session.flashes('info')app.session.flashbag.get('info')

4

1 に答える 1

0

それはSymfony2.1のバグによるものです。

ドキュメントには、関数はthen$session->invalidate()と同じであると記載されていますが、これは、私の例のフラッシュメッセージが、後者を使用した場合に表示され、最初の場合は表示されないためではありません。$session->clear()$session->migrate()

SymfonyのGithubでこの問題を参照してください。

于 2012-09-11T11:56:26.990 に答える