在拉拉维尔处理过期的代币
在 laravel 5 中处理过期令牌的最佳方法是什么?
我的意思是我有一个页面,它有一些执行ajax请求的链接。当页面加载时,它们可以正常工作,但是当我等待一段时间时,我会收到一个令牌不匹配错误。
现在,我必须刷新页面才能使其再次工作。但是,我不想刷新页面。我想要一些方法来刷新令牌或其他一些解决方法来修复它。
我希望你明白我的观点。
在 laravel 5 中处理过期令牌的最佳方法是什么?
我的意思是我有一个页面,它有一些执行ajax请求的链接。当页面加载时,它们可以正常工作,但是当我等待一段时间时,我会收到一个令牌不匹配错误。
现在,我必须刷新页面才能使其再次工作。但是,我不想刷新页面。我想要一些方法来刷新令牌或其他一些解决方法来修复它。
我希望你明白我的观点。
我认为@UX实验室的答案具有误导性。然后@jfadich的评论似乎完全不正确。
对于 2017 年 5 月的 Laravel 5.4,我通过以下方式解决了这个问题:
在:web.php
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
});
在你眼中的javascript中:
$(document).ready(function () {
setInterval(keepTokenAlive, 1000 * 60 * 15); // every 15 mins
function keepTokenAlive() {
$.ajax({
url: '/keep-token-alive', //https://stackoverflow.com/q/31449434/470749
method: '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'));
});
}
});
请注意,不得在 中的排除项中列出。正如 @ITDesigns.eu 在注释中暗示的那样,此路由必须验证当前是否存在有效的令牌,并且只需要延长其过期时间。'keep-token-alive'
VerifyCsrfToken.php
我的Laravel网站允许用户观看视频(一小时长),它使用ajax每分钟发布他们的进度。
但是许多用户加载页面,然后直到几个小时后才开始播放视频。
我不知道为什么他们在观看之前这么长时间就将浏览器选项卡打开,但他们确实如此。
然后,我会在我的日志中得到大量的TokenMismatch异常(并且会错过他们的进度数据)。
在 中,我从 120 分钟变为 360 分钟,但这仍然不够。我不想让它超过6个小时。因此,我需要启用此页面以通过ajax频繁地扩展会话。session.php
'lifetime'
在:web.php
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.';
});
在你眼中的javascript中:
<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',
method: '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',
method: 'post',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
}).then(function (d) {
$('body').prepend('<div>' + new Date() + ' Result of test: ' + d + '</div>');
});
});
});
})();
在 中,出于测试目的,暂时更改为非常短的内容。session.php
'lifetime'
然后四处玩。
这就是我如何了解Laravel令牌的工作原理,以及我们如何真正只需要经常成功发布到受CSRF保护的路由,以便令牌继续有效。
更新2022;该方法永远不会创建新令牌,它只是从当前会话加载现有的CSRF令牌(如果有,并返回它)。csrf_token()
但这会诱使您认为它有效,因为Laravel增加了现有CSRF令牌的使用寿命,并且每次都会向受CSRF保护的路由发出请求。
有关真正创建新的 CSRF 令牌的实现,请参阅:
stackoverflow.com/ 使用Ajax获取新的CSRF令牌?
解决它的方法是,实际上每隔一段时间就获得新令牌,否则您将破坏csrf令牌的目的:
<html>
<head>
<meta name="csrf_token" content="{{ csrf_token() }}">
</head>
<body>
<script type="text/javascript">
var csrfToken = $('[name="csrf_token"]').attr('content');
setInterval(refreshToken, 3600000); // 1 hour
function refreshToken(){
$.get('refresh-csrf').done(function(data){
csrfToken = data; // the new token
});
}
setInterval(refreshToken, 3600000); // 1 hour
</script>
</body>
</html>
在拉拉维尔路线中
Route::get('refresh-csrf', function(){
return csrf_token();
});
我很抱歉,如果出现任何语法错误,已经很长时间没有使用jquery了,但我想你明白了