web-dev-qa-db-ja.com

Laravel CSRFトークンを構築してチェックするのはどの程度具体的ですか?

公開サイトでLaravelのCSRF保護を使用しています。ただし、Laravelはセッションを使用してこれを維持するため、ユーザーがコンピューターから離れて、以前開いたままにしていたページに戻って、ajaxリクエストを見つけるだけで済むのではないかと心配しています。 tは機能します。セッションがタイムアウトしたため(トークンが検証されなくなったため)、ajaxリクエストは機能しません。これらのユーザーが「ログイン」した場合は、単にログインページにリダイレクトすることができます。がパブリックユーザーである場合、ユーザーはページを更新して機能を回復する必要があります(厄介です)。

それとも私はこれについて間違っていますか? CSRFトークンはLaravelによって検証されますか(セッションがタイムアウトした後でも、ページは引き続きトークンを送信します...しかし、Laravel最適な解決策は、トークンを部分的にタイムスタンプに基づいて設定し、セッションの時間制限とは別にトークンの有効期限を指定できるようにすることです。CSRFトークンを2日間持続させることができます(つまり、それらだけを使用できます)。 2日間離れたユーザーは、デッドページに戻ります)。

最終的にこれは私の質問に私をもたらします:これを処理するLaravelフレームワークの特定のコードはどこにありますか?私は現在それを見つけようとしています。また、そこにありますか?簡単に置き換えることができます。または、ページに出力するために独自のバージョンのcsrf_token();を作成する必要があります。その後、それに合わせて独自のルートフィルターを作成する必要があります。

20
prograhammer

Laravelは、トークンをセッションに保存しておくことでそれを容易にしますが、コードは実際にはあなたのものです(必要に応じて変更できます)。 _filters.php_を見てください。

_Route::filter('csrf', function()
{
    if (Session::token() != Input::get('_token'))
    {
        throw new Illuminate\Session\TokenMismatchException;
    }
});
_

ルートがある場合は、次のようになります。

_Route::post('myform', ['before' => 'csrf', 'uses' => 'MyController@update']);
_

また、ユーザーセッションが期限切れになると例外が発生しますが、自分で作業を行い、自分のトークンをどこにでも保存して、その例外をスローする代わりに、ユーザーをログインページにリダイレクトできます。

_Route::filter('csrf', function()
{
    if (MySession::token() != MyCSRFToken::get())
    {
        return Redirect::to('login');
    }
});
_

そして、はい、あなたはあなた自身のcsrf_token()を作成することができます、あなたはLaravelがする前にそれをロードする必要があります。 Laravelソースコードのhelpers.phpファイルを見ると、その関数がまだ存在しない場合にのみ作成されることがわかります。

_if ( ! function_exists('csrf_token'))
{
    function csrf_token()
    {
       ...
    }
}
_

これはよくある質問になっているので、非常にうまく機能している特定のソリューションを投稿することにしました...

ほとんどの場合、すべてのページの上部に使用するheader.phpまたは一部のビューがあります。これが、<head>セクションにあることを確認してください。

<meta name="_token" content="<?=csrf_token(); ?>" />  

あなたのfilters.phpで:

Route::filter('csrf', function() 
{
   if (Request::ajax()) {
        if(Session::token() != Request::header('X-CSRF-Token')){
            throw new Illuminate\Session\TokenMismatchException;
        } 
    }
});

そしてあなたのroutes.phpで

Route::group(array('before' => 'csrf'), function(){

    // All routes go in here, public and private

});
4
prograhammer