📅  最后修改于: 2023-12-03 15:02:34.753000             🧑  作者: Mango
在 Web 应用程序中,跨站点请求伪造(Cross-Site Request Forgery,CSRF)攻击是一种常见的攻击方式。为了防止 CSRF 攻击,Laravel 提供了 CSRF 令牌和保护机制。
CSRF 攻击是指攻击者通过伪造用户请求,从而在该用户的帐户下执行非法操作的攻击行为。如果用户在已经登录的状态下,打开了攻击者发来的链接或者点击了攻击者预先准备好的按钮,那么攻击者就可以伪造用户身份,发起一系列的恶意请求。
为了避免 CSRF 攻击,Laravel 提供了 CSRF 令牌机制。CSRF 令牌是在用户登录的时候生成的一个随机的字符串,用于验证用户提交表单的身份。每当用户提交一个表单时,Laravel 会检查表单中的 CSRF 令牌是否与当前用户会话中的令牌一致,如果不一致,Laravel 就会拒绝该请求。
生成 CSRF 令牌可以使用 csrf_field()
辅助函数,该函数会输出一个包含随机令牌的隐藏的表单域(在 Blade 模板中):
<form method="POST" action="/profile">
@csrf
<!-- 其他表单域 -->
</form>
除了 CSRF 令牌以外,Laravel 还提供了一些 CSRF 保护机制,用于进一步加强 CSRF 防护。
Laravel 内置了一个 CSRF 中间件,用于验证所有由 POST、PUT、DELETE 请求发起的表单请求。如果表单请求不携带 CSRF 令牌或者令牌无效,Laravel 会返回一个 419 HTTP 提示错误。
你可以在 Laravel 的路由文件中使用 middleware
方法标记需要被 CSRF 中间件保护的路由:
Route::middleware(['auth', 'csrf'])->group(function () {
// 需要 CSRF 保护的路由
});
除了使用隐藏的表单域传递 CSRF 令牌以外,Laravel 还提供了通过自定义请求头传递 CSRF 令牌的方式。在 Laravel 的默认应用程序模板中,会包含一个 <meta>
标签用于在所有页面中嵌入 CSRF 令牌。此外,在任何 AJAX 请求中,Laravel 还会在响应头中附带一个名为 X-CSRF-TOKEN
的 CSRF 令牌。
你可以使用 JavaScript 将此 CSRF 令牌设置为每个 Axios 请求或 Vue.js HTTP 请求头:
axios.defaults.headers.common['X-CSRF-TOKEN'] = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
对于纯 API 的应用程序,Laravel 还提供了一种基于令牌的 CSRF 保护。在这种情况下,Laravel 将会使用一个 API 令牌来代替 CSRF 令牌。你可以使用 api
中间件来启用基于 API 的 CSRF 保护:
Route::middleware(['auth:api'])->group(function () {
// 需要基于 API 的 CSRF 保护的路由
});
Laravel 提供了丰富的 CSRF 保护机制,包括 CSRF 令牌、CSRF 中间件、X-CSRF-TOKEN 头以及基于 API 的 CSRF 保护。使用这些机制可以有效防止 CSRF 攻击,帮助你的应用程序更加安全。