Я думаю, что ответ от @UX Labs вводит в заблуждение. И тогда комментарий от @jfadich кажется совершенно неправильным.
Для Laravel 5.4 в мае 2017 года я решил проблему следующим образом:
Вот ответ, который работает
В Route::post('keep-token-alive', function() { return 'Token must have been valid, and the session expiration has been extended.'; //https://stackoverflow.com/q/31449434/470749 });
:
$(document).ready(function () {
setInterval(keepTokenAlive, 1000 * 60 * 15); // every 15 mins
function keepTokenAlive() {
$.ajax({
url: '/keep-token-alive', //https://stackoverflow.com/q/31449434/470749
type: 'post',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
}).then(function (result) {
console.log(new Date() + ' ' + result + ' ' + $('meta[name="csrf-token"]').attr('content'));
});
}
});
В javascript, на ваш взгляд:
'keep-token-alive'
Обратите внимание, что вы не должны перечислять VerifyCsrfToken.php
исключения session.php
. Как @ ITDesigns.eu подразумеваемого в комментариях, это очень важно для этого маршрута , чтобы убедиться , что есть действительный маркер в настоящее время , и что он просто должно быть его действие продлено.
Почему этот подход решает мою проблему
Мой сайт Laravel позволяет пользователям смотреть видео (час), и он использует ajax для публикации своего прогресса каждую минуту.
Но многие пользователи загружают страницу, а затем не запускают видео до много часов спустя.
Я не знаю, почему они оставляют свою вкладку браузера открытой до того, как смотреть, но они это делают.
И тогда я получу тонны исключений TokenMismatch в своих журналах (и пропустил бы данные о их прогрессе).
В 'lifetime'
, я изменился web.php
с 120 до 360 минут, но этого все еще было недостаточно. И я не хотел делать это дольше 6 часов. Поэтому мне нужно было включить эту страницу, чтобы часто расширять сеанс с помощью ajax.
Как вы можете проверить это и понять, как работают токены:
В Route::post('refresh-csrf', function() {//Note: as I mentioned in my answer, I think this approach from @UX Labs does not make sense, but I first wanted to design a test view that used buttons to ping different URLs to understand how tokens work. The "return csrf_token();" does not even seem to get used. return csrf_token(); }); Route::post('test-csrf', function() { return 'Token must have been valid.'; });
:
<button id="tryPost">Try posting to db</button>
<button id="getNewToken">Get new token</button>
(function () {
var $ = require("jquery");
$(document).ready(function () {
$('body').prepend('<div>' + new Date() + ' Current token is: ' + $('meta[name="csrf-token"]').attr('content') + '</div>');
$('#getNewToken').click(function () {
$.ajax({
url: '/refresh-csrf',
type: 'post',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
}).then(function (d) {
$('meta[name="csrf-token"]').attr('content', d);
$('body').prepend('<div>' + new Date() + ' Refreshed token is: ' + $('meta[name="csrf-token"]').attr('content') + '</div>');
});
});
$('#tryPost').click(function () {
$.ajax({
url: '/test-csrf',
type: 'post',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
}).then(function (d) {
$('body').prepend('<div>' + new Date() + ' Result of test: ' + d + '</div>');
});
});
});
})();
В javascript, на ваш взгляд:
session.php
В 'lifetime'
, временно меняйте lifetime
что-то очень короткое для целей тестирования.
Затем поиграйте.
Вот как я узнал, как работает токен Laravel и как нам просто нужно успешно отправлять POST на защищенный CSRF маршрут, чтобы токен оставался действительным.