2

SecurityServiceProviderを使用して Silex アプリケーションを保護していますが、 logout_pathルートに移動してユーザーがログアウトした後にメッセージを表示したいと考えています。

私のテンプレートが後で自動的に表示できるように、メッセージはセッションフラッシュバッグに保存する必要があります。

アプリケーションミドルウェアを追加しようとしましたが、コードをフックできませんでした。セキュリティの後に発生し、セキュリティがホームページにリダイレクトされた後に発生するため、before フックが機能していないようです。

Application::EARLY_EVENTの before フックは、私の知る限り、セキュリティ プロバイダがログアウト後にセッションを破棄するため、早すぎるようです。

ある種の機能するがおそらく汚い解決策を見つけようとする前に、この場合の最良/最もクリーンな解決策は何でしょうか?

更新:ログアウト イベント ハンドラーの npms ヒントの後、Google でこの記事を見つけました。この記事では、Symfony で問題に非常にうまく取り組む方法が説明されています。

ただし、Silex では状況が少し異なり、SecurityServiceProviderのソースを読んだ後、このソリューションを思いつきました。

$app['security.authentication.logout_handler._proto'] = $app->protect(function ($name, $options) use ($app) {
    return $app->share(function () use ($name, $options, $app) {
        return new CustomLogoutSuccessHandler(
            $app['security.http_utils'],
            isset($options['target_url']) ? $options['target_url'] : '/'
        );
    });
});

class CustomLogoutSuccessHanler extends DefaultLogoutSuccessHandler {

    public function onLogoutSuccess(Request $request)
    {
        $request->getSession()->getFlashBag()->add('info', "Logout success!");
        return $this->httpUtils->createRedirectResponse($request, $this->targetUrl);
    }
}

ただし、問題は、リダイレクト後に flashbag メッセージが存在しないことです。そのため、ログアウト成功ハンドラーが実行された後にセッションが破棄されているようです...または何か不足していますか? これは正しい方法ですか?

更新:まだ適切な解決策をまだ見つけていません。しかし、これは機能します。

ログアウトのターゲット URL にパラメーターを追加し、それを使用してログアウトが行われたかどうかを検出します。

$app->register( new SecurityServiceProvider(), array(
    'security.firewalls' => array(
        'default' => array(
            'pattern'=> '/user',
            'logout' => array(
                'logout_path' => '/user/logout',
                'target_url' => '/?logout'
            ),
        )
    )
));
4

1 に答える 1

2

私は同じ問題を抱えていましたが、あなたの考えが私を解決に導いてくれました、ありがとう!

最初にsecurity.firewallでログアウトを定義します。

$app->register(new Silex\Provider\SecurityServiceProvider(), array(
    'security.firewalls' => array(
        'general' => array(
            'logout' => array(
                'logout_path' => '/admin/logout',
                'target_url' => '/goodbye'
            )
        )
    ),
));

ログアウトに必要なGETパラメータ (この場合はredirectmessage、およびpid ) を処理するCustomLogoutSuccessHandlerを作成します。

class CustomLogoutSuccessHandler extends DefaultLogoutSuccessHandler
{

    public function onLogoutSuccess(Request $request)
    {
        // use another target?
        $target = $request->query->get('redirect', $this->targetUrl);

        $parameter = array();
        if (null != ($pid = $request->query->get('pid'))) {
            $parameter['pid'] = $pid;
        }
        if (null != ($message = $request->query->get('message'))) {
            $parameter['message'] = $message;
        }
        $parameter_str = !empty($parameter) ? '?'.http_build_query($parameter) : '';

        return $this->httpUtils->createRedirectResponse($request, $target.$parameter_str);
    }
}

ハンドラーを登録します。

$app['security.authentication.logout_handler.general'] = $app->share(function () use ($app) {
    return new CustomLogoutSuccessHandler(
        $app['security.http_utils'], '/goodbye');
});

これを期待どおりに動作させる秘訣は、別のルートを使用してログアウトすることです。

$app->get('/logout', function() use($app) {
    $pid = $app['request']->query->get('pid');
    $message = $app['request']->query->get('message');
    $redirect = $app['request']->query->get('redirect');
    return $app->redirect(FRAMEWORK_URL."/admin/logout?pid=$pid&message=$message&redirect=$redirect");
});

/logout必要なパラメータを設定し、通常のログアウトを実行します/admin/logout

今、あなたは使用することができます

/logout?redirect=anywhere

ログアウト後に他のルートにリダイレクトするか、

/logout?message=xyz

(エンコードされた) /さようならダイアログでメッセージを表示します。

于 2013-10-27T04:52:31.957 に答える