CSRF 防护
CSRF(跨站请求伪造)防护用于防止恶意网站冒充用户提交表单。
配置
在 config/common.php中配置:
'csrf' => [
'token_lifetime' => 3600, // Token有效期(秒),默认1小时
'token_name' => 'csrf_token', // Token字段名
'auto_delete' => false, // 验证后是否删除(false=可重复使用)
],推荐配置:
- 普通表单:
token_lifetime => 3600(1小时) - 敏感操作:
token_lifetime => 300(5分钟),auto_delete => true - 长表单:
token_lifetime => 7200(2小时)
基本使用
视图中生成 Token
<form method="post">
<input type="hidden" name="csrf_token" value="<?=\startmvc\core\Csrf::token()?>">
<!-- 其他表单字段 -->
</form>控制器中验证
if (!\startmvc\core\Csrf::check()) {
$this->error('非法提交!');
}
常用方法
// 生成 Token(默认有效期)
Csrf::token()
// 生成 Token(自定义有效期,单位:秒)
Csrf::token(false, 1800) // 30分钟
// 验证 Token(使用配置的删除策略)
Csrf::check()
// 验证后删除(一次性使用)
Csrf::check(true)
// 验证后不删除(可重复使用)
Csrf::check(false)
// 刷新 Token
Csrf::refresh()
// 获取剩余有效时间(秒)
Csrf::getTokenTTL()
使用场景
普通表单
// 视图
// 控制器
if (!Csrf::check()) {
$this->error('非法提交!');
}
敏感操作(支付、删除等)
// 视图:5分钟有效期
// 控制器:验证后删除
if (!Csrf::check(true)) {
$this->error('非法提交!');
}
AJAX 请求
// 从表单获取 token
ice.ajax({
form: '#form', // 自动包含 csrf_token
url: '/submit'
});
// 手动添加 token
ice.ajax({
url: '/submit',
data: {
csrf_token: document.querySelector('input[name=csrf_token]').value,
// 其他数据
}
});
常见问题
Q: 提示"非法提交"?
A: Token 可能过期或不存在,检查表单是否包含 csrf_token 字段,或增加 token_lifetime。
Q: 刷新页面后提交失败?
A: 确保 auto_delete => false,允许 token 重复使用。
Q: 多标签页冲突?
A: 不会冲突,token 在有效期内可在多个标签页使用。
Q: 如何在 API 中使用?
A: 可通过 POST 参数或 HTTP Header(X-CSRF-TOKEN)传递 token。