【PHP】ThinkPHP6开启CSRF表单验证

561 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

使用原因

项目使用非前后端分离的情境下,提交表单时,开启CSRF中间件能提高操作安全性。

简单配置

开启session中间件与csrftoken验证中间件

# 修改app/middleware.php,去掉SessionInit类注释并增加FormTokenCheck类
<?php
// 全局中间件定义文件
return [
    // 全局请求缓存
    // \think\middleware\CheckRequestCache::class,
    // 多语言加载
    // \think\middleware\LoadLangPack::class,
    // Session初始化
     \think\middleware\SessionInit::class,
    // FormToken验证
    \think\middleware\FormTokenCheck::class,
];

ps:本人直接使用全局中间件来演示。

两种提交数据的场景

表单提交

1.在form表单内设置隐藏域,生成CsrfToken

# 第一种形式:生成隐藏域表单
<?=token_field()?>
# 第二种形式:定义token名称并设置值
<input type="hidden" name="__token__" value="<?=token()?>" />

2.简单HTML实例代码

<!DOCTYPE html>
<html lang="en">
 
<head>
    <?=token_meta()?>
</head>
 
<body class="bg-gradient-primary">
 
<div class="container">
    <form id="loginForm" class="user" action="/admin/doLogin" method="post">
        <?=token_field()?>
        <input value="123456789@qq.com" name="account">
        <input value="123456" name="password" type="password">
        <a onclick="doLogin()" href="#" class="btn">登录</a>
    </form>
</div>
</body>
</html>
<script>
  function doLogin()
  {
     $('#loginForm').submit();
  }
</script>

ajax异步提交

1.生成meta标签

# 第一种形式:直接通过方法生成meta标签,放置在页面head块里
<?=token_meta()?>
# 第二种形式:定义meta名称并设置值
<meta name="csrf-token" content="<?=token()?>">

2.调用ajax时,通过设置headers参数携带CsrfToken

let data = $('form').serializeArray();
$.ajax({
    type:'POST',
    url: '/admin/doLogin',
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    },
    data:data,
    success:function (res) {
      console.log(res)
    },
    error:function (err) {
      console.log(err)
    }
})

3.简单HTML实例代码

<!DOCTYPE html>
<html lang="en">
 
<head>
    <?=token_meta()?>
</head>
 
<body class="bg-gradient-primary">
 
<div class="container">
    <form id="loginForm" class="user">
        <input value="123456789@qq.com" name="account">
        <input value="123456" name="password" type="password">
        <a onclick="doLogin()" href="#" class="btn">登录</a>
    </form>
</div>
</body>
</html>
<script>
  function doLogin()
  {
    let data = $('#loginForm').serializeArray();
    $.ajaxSetup({
      headers: {}
    })
    $.ajax({
      type:'POST',
      url: '/admin/doLogin',
      headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
      },
      data:data,
      success:function (res) {
        console.log(res)
      },
      error:function (err) {
        console.log(err)
      }
    })
  }
</script>

其他

赋上TP6文档地址,更多细节可自行查阅:www.kancloud.cn/manual/thin…