StartMVC开发手册

可以快速上手的开发文档

手册目录

Csrf防护类

CSRF防护

CSRF(跨站请求伪造)防护用于防止恶意网站冒充当前用户提交表单或发送请求。

启用方式

StartMVC 推荐通过全局中间件开启 CSRF 防护。启用后,POSTPUTDELETEPATCH 请求会自动校验 Token。

config/middleware.php

return [
 'global' => [
 'app\\middleware\\CsrfMiddleware',
 ],
];


配置

config/common.php 中配置:

'csrf' => [
 'token_lifetime' => 3600, // Token有效期(秒)
 'token_name' => 'csrf_token', // Token字段名
 'auto_delete' => false, // 验证后是否自动删除
 'exclude' => [ // 无需校验的路径,支持 * 通配符
 // 'api/webhook',
 // 'api/open/*',
 ],
],


推荐配置:

  • 普通表单:token_lifetime => 3600
  • 敏感操作:token_lifetime => 300auto_delete => true
  • 长表单:token_lifetime => 7200

视图中使用

普通表单

推荐使用 csrf_field() 生成隐藏域:

<form method="post" action="/save">
 <?php echo csrf_field(); ?>
 <input type="text" name="title">
 <button type="submit">提交</button>
</form>

AJAX 请求

在页面 <head> 中输出:

<?php echo csrf_meta(); ?>

前端请求示例:

<script>
const token = document.querySelector('meta[name="csrf-token"]').content;

fetch('/save', {
 method: 'POST',
 headers: {
 'X-CSRF-TOKEN': token,
 'Content-Type': 'application/json'
 },
 body: JSON.stringify({title: 'test'})
});
</script>

手动获取 Token

<?php echo csrf_token(); ?>

特殊场景

一次性 Token

适合删除、支付、确认操作等敏感请求:

$token = \startmvc\core\Csrf::token(false, 300);

配合配置:

'auto_delete' => true

表示验证成功后立即失效。

排除校验路径

以下场景通常需要排除 CSRF 校验:

  • 第三方支付回调
  • Webhook 回调
  • 对外开放 API

示例:

'exclude' => [
 'api/webhook',
 'api/open/*',
],

常用方法

\startmvc\core\Csrf::token(); // 获取或生成Token
\startmvc\core\Csrf::token(false, 300); // 指定有效期
\startmvc\core\Csrf::check(); // 手动校验
\startmvc\core\Csrf::check(true); // 校验后删除
\startmvc\core\Csrf::refresh(); // 刷新Token
\startmvc\core\Csrf::getTokenTTL(); // 获取剩余有效时间
\startmvc\core\Csrf::unsetToken(); // 删除Token

说明:

  • 已启用 CsrfMiddleware 时,通常不需要在控制器中重复调用 Csrf::check()
  • Csrf::check() 主要用于未走中间件的特殊场景

Token 提交方式

系统按以下顺序读取 Token:

  1. POST 字段:csrf_token
  2. 请求头:X-CSRF-TOKEN
  3. 请求头:X-XSRF-TOKEN

常见问题

提示 403 或“CSRF token 验证失败”?
检查表单是否输出了 csrf_field(),或 AJAX 是否正确传递了请求头。

页面停留太久后提交失败?
说明 Token 已过期,可适当增大 token_lifetime

刷新页面后旧表单失效?
请检查是否启用了 auto_delete => true

多标签页会冲突吗?
默认不会。只要 Token 未过期且未被删除,就可以重复使用。