内容简介:跨站请求伪造(CSRF)是一种通过伪装授权用户的请求来攻击授信网站的恶意漏洞。Laravel 通过自带的 CSRF 保护中间件让避免应用遭到跨站请求伪造攻击变得简单:Laravel 会自动为每一个被应用管理的有效用户会话生成一个 CSRF “令牌”,然后将该令牌存放在 Session 中,该令牌用于验证授权用户和发起请求者是否是同一个人。
简介
跨站请求伪造(CSRF)是一种通过伪装授权用户的请求来攻击授信网站的恶意漏洞。
Laravel 通过自带的 CSRF 保护中间件让避免应用遭到跨站请求伪造攻击变得简单:Laravel 会自动为每一个被应用管理的有效用户会话生成一个 CSRF “令牌”,然后将该令牌存放在 Session 中,该令牌用于验证授权用户和发起请求者是否是同一个人。
任何时候在 Laravel 应用中定义 HTML 表单,都需要在表单中引入 CSRF 令牌字段,这样 CSRF 保护中间件才能够对请求进行验证。要想生成包含 CSRF 令牌的隐藏输入字段,可以使用 Blade 指令 @csrf
:
<form method="POST" action="/profile"> @csrf ... </form>
中间件组 web
中的中间件 VerifyCsrfToken
会自动为我们验证请求输入的 token 值和 Session 中存储的 token 是否一致,如果没有传递该字段或者传递过来的字段值和 Session 中存储的数值不一致,则会抛出异常。
为了演示该功能,我们在 routes/web.php
中定义一组测试路由:
Route::get('form_without_csrf_token', function (){ return '<form method="POST" action="/hello_from_form"><button type="submit">提交</button></form>'; }); Route::get('form_with_csrf_token', function () { return '<form method="POST" action="/hello_from_form">' . csrf_field() . '<button type="submit">提交</button></form>'; }); Route::get('hello_from_form', function (){ return 'hello laravel!'; });
我们在浏览器中访问 http://blog.test/form_without_csrf_token
并点击页面上的提交按钮时,页面报错,抛出 MethodNotAllowedHttpException
异常,出现这个异常往往就是意味着没有传递 CSRF 令牌字段或者传递的令牌字段不正确:
而当我们访问 http://blog.test/form_csrf_token
并点击页面上的提交按钮时,页面显示正常。
注:CSRF 中间件只只作用于 routes/web.php
中定义的路由,因为该文件下的路由分配了 web
中间件组,而 VerifyCsrfToken
位于 web
中间件组中。
CSRF 令牌 & JavaScript
构建 JavaScript 驱动的应用时,为方便起见,可以让 JavaScript HTTP 库自动在每个请求中添加 CSRF 令牌。默认情况下, resources/assets/js/bootstrap.js
文件会将 csrf-token
meta 标签值注册到 Axios HTTP 库。如果你没有使用这个库,则需要手动在应用中配置该实现。
排除指定 URL 不做 CSRF 安全校验
有时候我们需要从 CSRF 保护中间件中排除一些 URL,例如,如果你使用了第三方支付系统(如支付宝或微信支付)来处理支付并用到他们提供的回调功能,这时候就需要从 Laravel 的 CSRF 保护中间件中排除回调处理器路由,因为第三方支付系统并不知道要传什么 token 值给我们定义的路由。
通常我们需要将这种类型的路由放到文件 routes/web.php
之外,比如 routes/api.php
。不过,如果必须要加到 routes/web.php
中的话,你也可以在 VerifyCsrfToken
中间件中将要排除的 URL 添加到 $except
属性数组:
<?php namespace App\Http\Middleware; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware; class VerifyCsrfToken extends Middleware { /** * 从 CSRF 验证中排除的 URL * * @var array */ protected $except = [ 'alipay/*', 'http://example.com/foo/bar', 'http://example.com/foo/*', ]; }
注:运行测试时 CSRF 中间件会自动禁止。
X-CSRF-Token
除了将 CSRF 令牌作为 POST 参数进行验证外,还可以通过设置 X-CSRF-Token
请求头来实现验证, VerifyCsrfToken
中间件会检查 X-CSRF-TOKEN
请求头。实现方式如下,首先创建一个 meta
标签并将令牌保存到该 meta
标签:
<meta name="csrf-token" content="{{ csrf_token() }}">
然后在 js 库(如 jQuery)中添加该令牌到所有请求头,这为基于 AJAX 的请求提供了简单、方便的方式来避免 CSRF 攻击:
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } });
注:默认情况下, resources/assets/js/bootstrap.js
文件会将 csrf-token
meta 标签值添加到 Axios HTTP 库,如果你没有使用这个库,则需要手动配置应用的行为。
X-XSRF-Token
Laravel 还会将 CSRF 令牌保存到名为 XSRF-TOKEN
的 Cookie 中,你可以使用该 Cookie 值来设置 X-XSRF-TOKEN
请求头。
一些 JavaScript 框架,比如 Angular 和 Axios,会为你自动进行上述设置,基本上你不太需要手动设置这个值。
最后, VerifyCsrfToken
中间件框架底层实现源码位于 vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php
,感兴趣的同学可以去一窥究竟。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- [ Laravel 5.7 文档 ] 基础组件 —— 日志
- [ Laravel 5.7 文档 ] 基础组件 —— 视图
- [ Laravel 5.7 文档 ] 基础组件 —— 路由
- [ Laravel 5.8 文档 ] 基础组件 —— 路由
- [ Laravel 5.8 文档 ] 基础组件 —— 视图
- [ Laravel 5.7 文档 ] 基础组件 —— 错误处理
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
HotSpot实战
陈涛 / 人民邮电出版社 / 2014-3 / 69
《HotSpot实战》深入浅出地讲解了HotSpot虚拟机的工作原理,将隐藏在它内部的本质内容逐一呈现在读者面前,包括OpenJDK与HotSpot项目、编译和调试HotSpot的方法、HotSpot内核结构、Launcher、OOP-Klass对象表示系统、链接、运行时数据区、方法区、常量池和常量池Cache、Perf Data、Crash分析方法、转储分析方法、垃圾收集器的设计演进、CMS和G......一起来看看 《HotSpot实战》 这本书的介绍吧!