
laravel框架默认对所有post、put、patch和delete请求强制执行csrf(cross-site request forgery)保护。csrf是一种恶意攻击,攻击者诱导用户执行他们不希望的操作,例如更改密码、转账等。为了防止此类攻击,laravel会为每个用户会话生成一个唯一的csrf令牌,并在每个请求中验证此令牌。
当用户提交一个POST请求时,Laravel会检查请求中是否包含有效的CSRF令牌。如果令牌缺失、无效或与服务器端会话中的令牌不匹配,框架就会抛出“419 | PAGE EXPIRED”错误,表示页面已过期,实际上是CSRF验证失败。
在单页面包含多个表单,或通过不同视图文件渲染的多个表单时,开发者可能会遇到一个表单提交成功,而另一个表单却报419错误的情况。尽管控制器中的数据处理逻辑可能完全相同,但问题的根源往往在于HTML表单本身。
考虑以下场景:一个页面上存在两个独立的表单,分别用于提交不同类型的数据。例如:
路由配置示例:
Route::group([
'prefix' => 'atribut',
'as' => 'atribut.'
], function () {
Route::group(['prefix' => 'tabHome', 'as' => 'tabHome.'], function () {
Route::get('', [AtributDashboardController::class, 'showTab'])->name('showTab');
// 第一个表单的提交路由
Route::post('addDataFirst', [AtributDashboardController::class, 'addDataFirst'])->name('addDataFirst');
// 第二个表单的提交路由
Route::post('addDataSecond', [AtributDashboardController::class, 'addDataSecond'])->name('addDataSecond');
});
});控制器方法示例:
use Illuminate\Http\Request; // 引入Request门面
class AtributDashboardController extends Controller
{
// 假设这里有模型实例的注入或初始化
// public function __construct()
// {
// $this->inpDataFirst = new InpDataFirst();
// $this->inpDataSecond = new InpDataSecond();
// }
public function addDataFirst(Request $request) // 使用依赖注入获取Request实例
{
$data = [
'name' => $request->nameForm,
'address' => $request->addressForm,
];
// $this->inpDataFirst->addData($data); // 假设有对应的数据处理逻辑
return redirect('atribut/tabHome')->with('success', '第一个表单数据添加成功!');
}
public function addDataSecond(Request $request) // 使用依赖注入获取Request实例
{
$data = [
'name' => $request->nameForm,
'address' => $request->addressForm,
];
// $this->inpDataSecond->addData($data); // 假设有对应的数据处理逻辑
return redirect('atribut/tabHome')->with('success', '第二个表单数据添加成功!');
}
}在这种结构下,如果第一个表单能够成功提交,而第二个表单却出现419错误,问题几乎可以确定是第二个表单的HTML结构中缺少了CSRF令牌。
Laravel的Blade模板引擎提供了一个简洁的指令@csrf,用于在表单中自动生成一个隐藏的CSRF令牌字段。这是解决419错误最直接和有效的方法。
错误的表单示例(缺少CSRF令牌):
<!-- 第一个表单 - 假设这里包含@csrf所以工作正常 -->
<form action="{{ route('atribut.tabHome.addDataFirst') }}" method="POST">
<!-- ... 表单字段 ... -->
<input type="text" name="nameForm">
<input type="text" name="addressForm">
<button type="submit">提交第一个表单</button>
</form>
<!-- 第二个表单 - 缺少@csrf,导致419错误 -->
<form action="{{ route('atribut.tabHome.addDataSecond') }}" method="POST">
<!-- ... 表单字段 ... -->
<input type="text" name="nameForm">
<input type="text" name="addressForm">
<button type="submit">提交第二个表单</button>
</form>正确的表单示例(添加@csrf指令):
要修复419错误,只需在所有使用POST方法的HTML表单内部,紧邻<form>标签的下一行,添加@csrf指令:
<!-- 第一个表单 - 确保包含@csrf -->
<form action="{{ route('atribut.tabHome.addDataFirst') }}" method="POST">
@csrf <!-- 关键:添加CSRF令牌 -->
<!-- ... 表单字段 ... -->
<input type="text" name="nameForm">
<input type="text" name="addressForm">
<button type="submit">提交第一个表单</button>
</form>
<!-- 第二个表单 - 修复后,添加@csrf -->
<form action="{{ route('atribut.tabHome.addDataSecond') }}" method="POST">
@csrf <!-- 关键:添加CSRF令牌 -->
<!-- ... 表单字段 ... -->
<input type="text" name="nameForm">
<input type="text" name="addressForm">
<button type="submit">提交第二个表单</button>
</form>当Blade模板被渲染时,@csrf指令会被转换为一个隐藏的输入字段,例如:
<input type="hidden" name="_token" value="随机生成的CSRF令牌字符串">
这个隐藏字段包含了当前用户会话的CSRF令牌,当表单提交时,Laravel会验证这个令牌,从而允许请求通过。
始终使用@csrf: 任何使用POST、PUT、PATCH或DELETE方法提交数据的HTML表单,都必须包含@csrf指令。这是Laravel安全机制的基础。
csrf_field()函数: 在旧版本的Laravel或某些特定场景下,你可能还会看到{{ csrf_field() }}。它的作用与@csrf完全相同,只是@csrf是Blade指令,更推荐使用。
AJAX请求的CSRF处理: 如果你的应用使用AJAX(如Axios、jQuery.ajax等)提交POST请求,你需要手动将CSRF令牌包含在请求头或请求体中。通常,最佳实践是在HTML的<head>部分设置一个meta标签来存储令牌,然后在JavaScript中读取并设置到请求头中:
<meta name="csrf-token" content="{{ csrf_token() }}">// 例如使用Axios
axios.defaults.headers.common['X-CSRF-TOKEN'] = document.querySelector('meta[name="csrf-token"]').getAttribute('content');排除CSRF验证: 在极少数情况下,你可能需要对某些路由禁用CSRF验证(例如,处理第三方Webhook)。这可以通过在app/Http/Middleware/VerifyCsrfToken.php文件的$except数组中添加相应的URI来实现。请谨慎使用此功能,因为它会降低应用的安全性。
“419 | PAGE EXPIRED”错误在Laravel中几乎总是指向CSRF令牌验证失败。对于HTML表单,解决方案非常简单:确保每个使用POST方法的表单都包含了@csrf Blade指令。理解CSRF保护的重要性,并正确地在所有数据提交点集成CSRF令牌,是构建安全、健壮Laravel应用的关键。遵循这些最佳实践,可以有效避免常见的表单提交问题,并提升用户体验。
以上就是解决Laravel中多表单提交419错误:CSRF令牌的正确使用的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号