Подтвердить что ты не робот

Как конкретно Laravel строит и проверяет токен CSRF?

Я использую Laravel CSRF-защиту на своем общедоступном сайте. Однако, поскольку Laravel использует сеанс для этого, я беспокоюсь, что пользователь может уйти со своего компьютера и вернуться на страницу, которую они ранее оставили открытой, только чтобы найти запросы ajax не работают. Запросы ajax не работают, потому что сеанс завершен (и токен больше не проверяет?). Если эти пользователи были "вошли в систему", я мог бы просто перенаправить их обратно на страницу входа. Поскольку они являются общедоступными пользователями, пользователь вынужден обновить страницу, чтобы вернуть ее работу (неудобно).

Или я ошибаюсь? Будет ли токен CSRF по-прежнему проверяться Laravel (даже после того, как сеанс завершился, страница все равно будет отправлять через токен... но что с этим сделает Laravel?). Оптимальным решением было бы, чтобы маркеры были частично основаны на временной отметке, так что мы могли бы ограничить лимиты лимитов токенов, кроме предельных сроков сеанса. Я мог бы сделать мои токены CSRF в течение 2 дней (так что только те пользователи, которые уходят в течение 2 дней, вернутся на мертвую страницу).

В конечном итоге это подводит меня к моему вопросу: Где конкретный код в структуре Laravel, который обрабатывает это? Я сейчас пытаюсь найти его. Кроме того, есть ли легкая замена в замене, которую я могу сделать, или я оставил, чтобы создать свою собственную версию csrf_token(); для вывода на мои страницы, а затем мне понадобится создать собственный фильтр маршрутов, чтобы пойти с ним.

4b9b3361

Ответ 1

Laravel просто упрощает это для вас, сохраняя токен, хранящийся в сеансе, но код на самом деле ваш (для изменения, как вы пожелаете). Взгляните на filters.php, вы должны увидеть:

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

Он сообщает нам, что если у вас есть маршрут:

Route::post('myform', ['before' => 'csrf', 'uses' => '[email protected]']);

И пользовательский сеанс истекает, он будет вызывать исключение, но вы можете самостоятельно выполнить эту работу, сохранить свой собственный токен, где бы вы ни находились, и вместо того, чтобы бросать это исключение, перенаправить пользователя на страницу входа:/p >

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

И да, вы можете создать свой собственный csrf_token(), вам просто нужно загрузить его до того, как Laravel сделает. Если вы посмотрите файл helpers.php в исходном коде Laravel, вы увидите, что он создает эту функцию только в том случае, если она еще не существует:

if ( ! function_exists('csrf_token'))
{
    function csrf_token()
    {
       ...
    }
}

Ответ 2

Поскольку это стало популярным вопросом, я решил опубликовать свое конкретное решение, которое работает очень хорошо...

Скорее всего, у вас будет заголовок 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;
        } 
    }
});

И в ваших route.php

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

    // All routes go in here, public and private

});