ThinkPHP5表单令牌刷新

当我制作一个登录页面时候发现验证码填写错误或者账号密码填写错误重新填写提交时,提示表单令牌错误,这时候就只能重新刷新页面重新填写,不怕麻烦的同学当然没关系了;

其他的账号密码复杂的就麻烦了,也许我只是输错了一个字符,你却让我刷新页面重新填写,未免太可恶了吧,于是当时一脑残想出了第一个办法:

首次尝试

既然我可以在不刷新页面的时候用js事件来更换验证码,表单令牌不也一样吗?就有了下面的代码:

1
$("[name='__token__']").val('{$Request.token}');

尝试之后发现这两个表单令牌值一样的,要通过事件更换一样无解啊,想到了用ajax,但是ajax需要有一个地址生成这个token,再写个控制器方法?其实差不多,虽然没写方法,利用了闭包路由

1
2
3
Route::get('refresh/token',function(){
return Request::token();
})->cache(false);

这样就有一个随时生成表单令牌的地址了,当你的ajax登录失败的时候,自动刷新token和验证码

1
2
3
4
$.get("{:url('@refresh/token')}", function(result){
$("[name='__token__']").val(result);
});
$('#captcha').attr('src', $('#captcha').attr('src')+'?'+Math.random());

修复

因为很久没用tp了,公司赶一个小项目,顺手拉了个5.0做了下,前端表单用到了这个表单令牌,用以上代码竟然报错了,大概意思是不存在这个静态方法,索性换了一种写法,完美。

1
2
3
4
5
6
use think\Request;
//刷新表单令牌;我的token隐藏输入框名字叫做__csrf__,改成你自己的即可
Route::get('refresh/token',function(){
$request = Request::instance();
return json(['token'=>$request->token('__csrf__', 'sha1')]);
});

同样前端提交表单后,js调用:

1
2
3
$.get("{:url('@refresh/token')}", function(res){
$("[name='__csrf__']").val(res.token);
});