thinkphp6令牌防止表单重复提交
2023-03-29 23:03:03
159
{{single.collect_count}}

使用TP框架的表单令牌功能

原理:生成一个token字符串,session中保存一次,页面中放一个;

页面发送请求时携带token字符串,控制器中进行验证,验证成功后重置。

生成token两种语法:

1.{:token()} 生成一个隐藏域, 存放token令牌

<input type="hidden" name="__token__" value="{:token()}" />

 也可以使用

{:token_field()}

得到 形似以下的代码

<input type="hidden" name="__token__" value="fe9f76dcda3ee3972b23ad0428934bb7">

2.在控制器生成

<?phpnamespace app\controller;use think\Request;use think\facade\View;class Index{public function index(Request $request){$token = $request->buildToken('__token__', 'sha1');View::assign('token', $token);return View::fetch();}}

然后在模板表单中使用:

<input type="hidden" name="__token__" value="{$token}" />

控制器中对token进行校验:

使用表单验证,在任何一个字段的验证规则中,加上 “token”规则

 /** * 登录 * @param Request $request * @return \think\response\Json|void */public function doLogin(Request $request){$result = ['code' => 200,'msg' => 'ok','data' =>[]];// code msg datatry {// 验证请求令牌$check = $request->checkToken('__token__');if(false === $check) {throw new ValidateException('invalid token');}$username = $request->post('username');$password = $request->post('password');# 验证非空validate(\app\admin\validate\Login::class)->check(['username' => $username,'password' => $password,]);$adminInfo = Manager::where('username','=',"{$username}")->find();if ($adminInfo) {// 判断密码if ($adminInfo->password == encryptPassword($password)) {Session::set('username',$adminInfo->username);//session#记录日志信息Log::write($username.'登录成功','info');return redirect('/admin/goodsList');} else{throw new \think\Exception('密码错误', 20002);}} else {abort(20001,'用户名不存在');}}catch (ValidateException $exception) {$result['msg'] = $exception->getError(); return json($result);}catch (\Exception $exception) {Log::write('测试日志信息,这是警告级别,并且实时写入','notice');$result['msg'] = $exception->getMessage();$result['code'] = $exception->getCode();return json($result);}}

AJAX提交

如果是AJAX提交的表单,可以将token设置在meta中

<meta name="csrf-token" content="{:token()}">

或者直接使用

{:token_meta()}

也可以在全局Ajax中使用这种方式设置X-CSRF-Token请求头并提交:

 headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}
回帖
全部回帖({{commentCount}})
{{item.user.nickname}} {{item.user.group_title}} {{item.friend_time}}
{{item.content}}
{{item.comment_content_show ? '取消' : '回复'}} 删除
回帖
{{reply.user.nickname}} {{reply.user.group_title}} {{reply.friend_time}}
{{reply.content}}
{{reply.comment_content_show ? '取消' : '回复'}} 删除
回帖
收起
没有更多啦~
{{commentLoading ? '加载中...' : '查看更多评论'}}