Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Добрый день.
Помогите, пож-та, новичку. Уже весь интернет облазил ничего не помогает.
Версия Laravel: 5.3.28
Версия PHP: 7.0.9
Операционная система и её версия: Windows 10 64bit
Вендор и версия Веб-сервера: XAMPP 3.2.2
Проблема в следующем.
Установил чистый laravel.
В роуты routes/web добавил следующий маршрут
Route::match(['get','post'],'/', ['uses'=>'IndexController@index' ,'as'=>'index']);
В папке app\Http\Controllers добавил IndexController.php со следующим кодом
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class IndexController extends Controller
{
public function index(Request $request)
{
$result = $request->session()->all();//получаем данные из сессии
dump($result);//отображаем данные на экране
return view('index'); //передаём данные в шаблон
}
}
В папке resources\views создал файл index.blade.php и добавил в него простую форму
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow"/>
<meta name="csrf-token" content="{{ csrf_token() }}" />
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Название страницы</title>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<form role="form" method="POST" action="{{ url('/') }}">
{{ csrf_field() }}
<input type="password" class="form-control input-lg my-width-100" name="password" placeholder="Введите пароль" required>
<button type="submit" class="btn btn-success btn-lg my-width-100 my-text-center">Войти</button>
</form>
</body>
</html>
При запуске страницы в сессии (в окне дампа) отображается значение _token.
Причём при каждом обновлении значение меняется и создаются новые файлы сессии
При отправки формы, выдаёт ошибку
Но если вернуться назад, то в сессию добавляются поля flash и _previous и форма начинает работать нормально.
Подскажите, как избавиться от данной ошибки.
Не в сети
Прости, нет возможности сейчас всё это громоздить себе и искать ошибку. Но на первый взгляд - просто не передаётся идентификатор сессии через cookie.
Не помешает проверить две вещи:
- включены ли в браузере куки
- изучи-ка файл КаталогПроекта/config/session.php
нет ли там чего-то вроде
'expire_on_close' => true,
Если эти проверки не дадут результата - я смогу подключиться завтра/послезавтра
Изменено tmanager (21.12.2016 11:01:23)
Не в сети
Спасибо за оперативный ответ.
- включены ли в браузере куки .
Куки в браузере включены. Проверял в браузерах
Firefox 50.1.0
Google Chrome 55.0.2883.87 m
Internet Explorer 9.0.8112.16421
- изучи-ка файл КаталогПроекта/config/session.php
нет ли там чего-то вроде'expire_on_close' => true,
проверил - есть строчка
'expire_on_close' => false,
пробовал менять на
'expire_on_close' => true,
результат тот же
Не в сети
Я поставил Ваш проект себе - и всё повторилось, как Вы описали.
Но вот что я потом сделал:
Изменил контроллер таким образом:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class IndexController extends Controller
{
public function index(Request $request)
{
$result = $request->session()->all();//получаем данные из сессии
$token = $result['_token'];
return view('index',['token'=>$token]); //передаём данные в шаблон
}
}
А в view вставил эту переменную
{{ $token }}
Так вот: стоит токен как впаянный при всех перезагрузках.
Похоже, функция dump() Вам подгадила. Какой-то странный ЯваСкрипт она добавляет. Который, похоже, что-то открывает через Аякс - и соответственно, открывает новую сессию и получает новый токен.
Если эта информация Вам не помогла - сорри, я свой лимит исчерпал. Ушел работать.
Не в сети
Спасибо огромнейшее. Помогло
Не в сети
Вот и прекрасно. И мне полезный опыт: я рано или поздно заюзал бы dump() и тоже бился бы...
Не в сети
Добрый вечер.
Рано я начал радоваться(((. Пришел домой, ошибка восстановилась.
Нашел закономерность. Если появляется ошибка и вернуться назад либо закрыть и открыть браузер, то ошибка исчезает на некоторое время.
Спустя некоторое время ошибка восстанавливается.
Буду искать решение дальше. Если есть предположения, буду благодарен.
Не в сети
Добрый день.
Вопрос закрыт.
Заново установил Laravel, убрал dump. Всё работает.
tmanager, спасибо за помощь.
Не в сети
Вылезла та же проблема.
Токен сессии оказывается неверный.
Не в сети
если токен не принимается обработчиком, то варианта существует по сути два – либо он не отправляется в запросе (отсутствует csrf_field() в форме, или нет нужного значения в аякс-запросе – там он может передаваться как в данных так и в заголовках запроса), либо на стороне сервера не загружается сессия – именно в ней сохраняется токен на стороне сервера, чтобы было с чем сравнить то что пришло в запросе.
диагностировать можно соответственно
а) через закладку Network в Dev Tools: проверить что сессия стартует при открытии страницы с формой вообще – сервер должен прислать Set-Cookie с кукой laravel_session (название по умолчанию, может быть изменено)
б) проверяем форму – открываем структуру документа и проверяем что там где был вызов csrf_field теперь красуется input type hidden с именем _token
в) при сабмите формы смотрим заголовки на закладке Network: у запроса должен быть заголовок Cookies содержащий правильное значение laravel_session, в данных формы должен отправляться _token. если запрос делается аяксом, токен может передаваться как обычно, а может – заголовком запроса X-CSRF-Token.
если всё на месте, значит фронтенд отрабатывает корректно. теперь смотрим бэкенд
а) сессии должны корректно сохраняться и восстанавливаться. за выбор способа работы с сессиями отвечает SESSION_DRIVER в .env а конкретные настройки лежат в config/session.php. по умолчанию стоит file – проверяем права доступа к storage/framework/sessions. если драйвер database – должна быть создана таблица сессий и настроено подключение к базе. для memcached и redis должны быть запущены и настроен доступ к соответствующим демонам. драйвера null и array не поддерживают сохранение данных никуда вообще – с ними CSRF-проверка работать не будет в любом случае. драйвер cookie не требует настроек так как передаёт все данные сразу в куках в шифрованном виде – неэффективно но просто и для того чтобы быстро что-то потестировать вполне подходит
б) если сессии настроены и работают – проверяем что сессия реально сохраняется и восстанавливается при запросах, за это отвечает миддлварь Illuminate\Session\Middleware\StartSession которая входит в группу миддлварей web. в версии 5.3 эта группа применена на маршрутах заданных в routes/web.php. в более ранних версиях оно задаётся явно в app\Http\routes.php с помощью группы Route::group(['middleware' => ['web']], function () { /* ... */ }); маршруты, которым не назначена группа web или явно миддлварь StartSession не получают сессии и соответственно не могут прочитать сохранённый токен
в) если сессии настроены, миддлвари прикреплены к маршрутам, где отображается и куда сабмитится форма, а токен всё равно нет тот – остаётся только установить xdebug и погулять по коду, проверяя где токены создаются и сравниваются, потому что на этом месте у меня закончилась фантазия как ещё можно сломать простой и надёжный как валенок механизм работы с CSRF-токенами
Не в сети
Если используете Laravel 5.3 то для защиты от CSRF (межсайтовая подделка запроса) при запросах типа POST, DELETE, PUT используется посредник VerifyCsrfToken и если соответствующий токен не представлен, генерируется ошибка. Этот токен автоматически генерируется Lavarel. Соответственно, либо необходимо его обеспечить или внести ваш маршрут в исключения из этого посредника. Подробности в документации https://laravel.com/docs/5.3/csrf
Не в сети
andrey_sunday - спасибо большое, помогло!)) Долго я с этой проблемой возился!
Изменено IvanKIM (28.04.2017 17:14:02)
Не в сети
Начал осваивать Laravel (5.4) и также столкнулся с этой ошибкой, подскажите где ошибка:
web.php:
// Отображение статичной страницы с формой добавления поста
Route::get('add-post', 'AboutController@add');
Route::post('add-post', 'AboutController@store')->name('postStore');
Контроллер AboutController.php:
// Указываем страницу-вид добавления поста
public function add() {
return view('addpost');
}
// Сохранение данных о новом посте в бд
public function store(Request $request) {
$result = $request->session()->all(); //получаем данные из сессии
$token = $result['_token'];
return view('addpost', ['token'=>$token]);
}
Модель Post.php:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
//
}
Вид addpost.blade.php:
@extends('templates/main')
@section('content')
<h1>Добавить пост</h1>
<p>Заполните все поля и нажмите отправить</p>
<form method="POST" action="{{ route('postStore') }}">
{{ csrf_field() }}
<p>Заголовок:</p>
<input type="text" name="Title"></input>
<p>Автор:</p>
<input type="text" name="Autor"></input>
<p>Короткое описание:</p>
<input type="text" name="PreviewPost"></input>
<p>Полное описание:</p>
<input type="text" name="FullPost"></input>
<br><br>
<button type="sumbit">Отправить</button>
</form>
@endsection
Изменено HellWalk (16.05.2017 13:04:22)
Не в сети
Если можно, пару уточняющих вопросов. Почему не используете resource controller ведь все равно еще надо будет предоставить возможность этот пост редактировать и удалять. Я вижу модель у вас есть, наверное и табличка в БД имеется, а куда и что сохраняем в контроллере непонятно. Есть ощущение что вам надо по изучать Laravel. Могу порекомендовать две книги https://leanpub.com/laravel-5-4-for-beginners и https://leanpub.com/codesmart обе на английском, но других путей изучать нет. Если совсем критично могу дать ссылку на видео курс https://webformyself.com/laravel/?utm_m … gn=laravel но это как крайний случай если совсем по английски не читаете.
Не в сети
Почему не используете resource controller
Не знал, что такое существует (делал по видео-уроку и запнулся на этой ошибке), спасибо за наводку.
Есть ощущение что вам надо по изучать Laravel.
Разумеется надо, этим сейчас и занимаюсь) За рекомендацию книг спасибо, но английский не знаю, по этому пока изучаю по видео-урокам.
Не в сети
Аналогичная ошибка выскакивает, только я вообще не использую контроллеры, у меня все до ужаса просто
xml<body> <form action="/comments" method="POST"> Имя: <input type="text" name="name"><br/> Комментарий:<br/> <textarea name="text" id="text" cols="30" rows="10"></textarea> <br/> <input type="submit" value="Добавить"> </form> </body>
Route::post('/comments',function (){
print_r($_POST);
});
и всё больше ничего нет....
GET работает без проблем
Изменено Yura_Yushkevich (29.07.2017 21:50:28)
Не в сети
В форму вставляйте скрытое поле
<form method="POST" action="/profile">
{{ csrf_field() }}
...
</form>
https://laravel.com/docs/5.3/csrf#csrf-introduction
Изменено Waddonator (30.07.2017 11:17:04)
Не в сети
Ничего не понял, просто вставить
{{ csrf_field() }}
между тегами <form>?
Так оно же отобразится на экране… (((
xml<form action="/comments" method="POST"> {{ csrf_field() }} Имя: <input type="text" name="name"><br/> Комментарий:<br/> <textarea name="text" id="text" cols="30" rows="10"></textarea> <!--<input type="hidden" name="_method" value="PUT">--> <br/> <input type="submit" value="Добавить"> </form>
Изменено Yura_Yushkevich (30.07.2017 17:16:19)
Не в сети
Не в сети
xml<form action="/comments" method="POST"> <input type="hidden" name="csrf_field" value="{{csrf_field() }}"> Имя: <input type="text" name="name"><br/> Комментарий:<br/> <textarea name="text" id="text" cols="30" rows="10"></textarea> <!--<input type="hidden" name="_method" value="PUT">--> <br/> <input type="submit" value="Добавить"> </form>
Не в сети
Не в сети
Если я в файле forma.html пропишу вот этот код
xml<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Форма</title> </head> <body> <form action="/comments" method="POST"> {{ csrf_field() }} Имя: <input type="text" name="name"><br/> Комментарий:<br/> <textarea name="text" id="text" cols="30" rows="10"></textarea> <!--<input type="hidden" name="_method" value="PUT">--> <br/> <input type="submit" value="Добавить"> </form> </body> </html>
то всё будет видно, вот к примеру
http://joxi.ru/n2YZMlBHjeZ7vA
Я это всё к чему, может у меня что-то не подключено что обрабатывает
xml{{ csrf_field() }}
Не в сети
Не в сети
Не в сети
Не в сети