直接上例子
表单如下
<div class="login-container"> <div class="loginbox bg-white"> <div class="loginbox-title">登录</div> <div class="loginbox-or"> <div class="or-line"></div> </div> <form method="post"> <input type="hidden" name="__token__" value="{$Request.token}" /> <div class="loginbox-textbox"> <input type="text" name="username" class="form-control" placeholder="用户名" /> </div> <div class="loginbox-textbox"> <input type="text" name="password" class="form-control" placeholder="密码" /> </div> <div class="loginbox-textbox"> <input name="captcha" type="text" class="form-control" placeholder="验证码" aria-describedby="basic-addon2"> <span class="input-group-addon" id="basic-addon2"><img src="{:captcha_src()}" id="img" alt="captcha" /></span> </div> <div class="loginbox-forgot"> <a href="">忘记密码?</a> </div> <div class="loginbox-submit"> <input type="button" id="login" class="btn btn-primary btn-block" value="Login"> </div> </form> <div class="loginbox-signup"> <a href="{:url('admin/index/register')}">注册账户</a> </div> </div>//使用ajax提交
$.ajax({ url:"{:url('admin/index/login')}", type:'post', data:$('form').serialize(), retType:'json', success:function (ret) { if (ret.code==1) { layer.msg(ret.msg,{ icon:6, time:2000 },function () { location.href=ret.url; } ) }else { layer.open({ title:'登录失败', content:ret.msg, icon: 5, anim:6 }) } }})
</div>
验证规则如下
protected $rule = [ 'username|用户名'=>'token|require', 'password|密码'=>'require', 'captcha|验证码'=>'require|captcha', 'repassword'=>'require|confirm:password', 'email|邮箱'=>'require|email' ];
第一次提交,将token提交验证没有问题(只要token被验证一次),第二次提交(ajax请求),由于是异步请求整个页面并没有刷新,自然无法获得新的token,则不能通过验证
解决方法
1 在控制器中使用生成新的token并返回
$ret=model('Admins')->login($data); //动态生成token,返回到视图中 //不要写在模型的验证前面 token方法中会保存session('__token__'),会设置新的token覆盖前面的token 使得验证永远不会成功
$token=$request->token(); if ($ret===true) $this->success('登录成功',url('admin/home/index')); elseif($ret===false) $this->error('登录失败:密码错误',url('admin/index/login'),["token"=>$token]); elseif($ret===0)
我设置的ajax接受的数据类型为json格式 thinkphp会自动将ajax请求返回json格式
2 在视图中设置新的token
//刷新验证码 $('#img').attr('src',"{:captcha_src()}") //刷新token ret success为返回的 $("input:hidden").attr('value',ret.data.token) layer.open({ title:'登录失败', content:ret.msg, icon: 5, anim:6