zl程序教程

您现在的位置是:首页 >  其他

当前栏目

ThinkPHP6项目基操(18.实战部分 表单令牌Token 防CSRF)

项目 实战 部分 表单 18 Token CSRF ThinkPHP6
2023-09-11 14:19:17 时间

0. 前言

表单令牌是为了防止表单重复提交,防止跨站请求伪造(Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF

1. TP6 令牌token使用

1.1 表单提交

如果使用了默认的模板引擎,可以直接使用下面的方式:

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

也可以直接使用

{:token_field()}

默认的令牌Token名称是__token__,如果需要自定义名称及令牌生成规则可以使用

{:token_field('__hash__', 'md5')}

第二个参数表示token的生成规则,也可以使用闭包。

1.2 AJAX提交

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

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

或者直接使用:

{:token_meta()}

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

$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});

2. TP6 令牌token验证

2.1 路由验证

然后在路由规则定义中,使用

Route::post('blog/save','blog/save')->token();

如果自定义了token名称,需要改成

Route::post('blog/save','blog/save')->token('__hash__');

令牌检测如果不通过,会抛出think\exception\ValidateException异常。

2.2 控制器验证

控制器里面手动进行令牌验证

namespace app\controller;

use think\exception\ValidateException;
use think\Request;

class Index
{
    public function index(Request $request)
    {
        $check = $request->checkToken('__token__');
        
        if(false === $check) {
            throw new ValidateException('invalid token');
        }

        // ...
    }
}

如果修改了tokentoken不存在,就会报错:
在这里插入图片描述

2.3 验证器验证

在你的验证规则中,添加token验证规则即可

protected $rule = [
    'name'  =>  'require|max:25|token',
    'email' =>  'email',
];

如果你的令牌名称不是__token__(假设是__hash__),验证器中需要改为:

protected $rule = [
    'name'  =>  'require|max:25|token:__hash__',
    'email' =>  'email',
];

⭐️重磅推荐:免费商用电商系统

😏想白嫖整个电商系统用来商用?
🤑想有自己的商城实现财富自由?
🤓想学习最佳实践提升自己技术?

快来进入🚀 传送门 🚀,开源免费、完整示例带你快速入门,轻松二开,走上人生巅峰!👨‍🎓
在这里插入图片描述