laravel的csrf token 的了解及使用
之前在项目中因为没有弄清楚csrf token的使用,导致发请求的话,一直请求失败,今天就一起来看一下csrf的一些东西。
1.Cross-site request forgery 跨站请求伪造,也被称为 “one click attack” 或者 session riding,通常缩写为 CSRF 或者 XSRF,是一种对网站的恶意利用。CSRF 则通过伪装来自受信任用户的请求来利用受信任的网站。
2.从字面意思就可以理解:当你访问 fuck.com
黑客页面的时候,页面上放了一个按钮或者一个表单,URL/action 为 http://you.com/delete-myself
,这样引导或迫使甚至伪造用户触发按钮或表单。在浏览器发出 GET 或 POST 请求的时候,它会带上 you.com
的 cookie,如果网站没有做 CSRF 防御措施,那么这次请求在 you.com
看来会是完全合法的,这样就会对 you.com
的数据产生破坏。
3.第三方恶意网站也是可以构造post请求并提交至被攻击网站的,所以POST方式提交只是提高了攻击的门槛而已,无法防范CSRF攻击,所以对post也要进行防范
关于csrf更多的请参考 https://segmentfault.com/q/1010000000713614 https://www.ibm.com/developerworks/cn/web/1102_niugang_csrf/
在laravel中为了防止csrf 攻击,设计了 csrf token
laravel默认是开启了csrf token 验证的,关闭这个功能的方法:
(1)打开文件:app\Http\Kernel.php
把这行注释掉:‘App\Http\Middleware\VerifyCsrfToken’
(2)打开文件 app\Http\Middleware\VerifyCsrfToken.php
修改handle方法为:
public function handle($request, Closure $next)
{
// 使用CSRF
//return parent::handle($request, $next);
// 禁用CSRF
return $next($request);
}
csrf的使用:
(1)在html的代码中加入:
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
(2)使用cookie 方式 ,将app\Http\Middleware\VerifyCsrfToken.php修改为:
<?php namespace App\Http\Middleware; use Closure;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier; class VerifyCsrfToken extends BaseVerifier { /**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
return parent::addCookieToResponse($request, $next($request));
} }
使用cookie方法就不用在每个页面都加入这个input 的 hidden 标签
还可以部分使用csrf检测部分不使用。
注:本文从laravel的csrf token开始到此参考:http://blog.csdn.net/proud2005/article/details/49995389
关于 laravel 的 csrf 保护更多的内容请参考 laravel学院文档:http://laravelacademy.org/post/6742.html
下面说说我们那个项目中的关于csrf token的使用:
在我的另一篇文章中也提到了我们那个项目中的使用过程
在中间件VerifyCsrfToken.php中修改内容为:
protected function tokensMatch($request)
{
// If request is an ajax request, then check to see if token matches token provider in
// the header. This way, we can use CSRF protection in ajax requests also.
$token = $request->ajax() ? $request->header('X-CSRF-TOKEN') : $request->input('_token');
return $request->session()->token() == $token;
} public function handle($request,\Closure $next){
//todo:需要在添加了登录验证之后,取消
//这样是在post请求的时候不进行csrf token验证
if($request->method() == 'POST')
{
return $next($request);
} return parent::handle($request,$next);
}
然后在vue中的bootstrap.js中的引入的axios的位置添加
window.axios.defaults.headers.common = { 'X-CSRF-TOKEN': document.querySelector('meta[name="X-CSRF-TOKEN"]').content, 'X-Requested-With': 'XMLHttpRequest' }; 在index.blade.php中添加
<meta name="X-CSRF-TOKEN" content="{{csrf_token()}}">
上面的代码都好理解,就是获取到 csrf_token令牌,然后提交,再经过中间件验证即可
下面重点来说一下 VerifyCsrfToken.php中间件
中间件的内容最开始应该只有一个 handle函数:这个是所有的都进行csrf token验证
public function handle($request,\Closure $next){
return parent::handle($request,$next);
}
现在项目中的这个中间件的内容
<?php namespace App\Http\Middleware; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier; class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
//
];
// protected $except = [
//
// '/classroom_upload',
// 'wk_upload',
// 'wechat',
// ];
protected function tokensMatch($request)
{
// If request is an ajax request, then check to see if token matches token provider in
// the header. This way, we can use CSRF protection in ajax requests also.
$token = $request->ajax() ? $request->header('X-CSRF-TOKEN') : $request->input('_token');
return $request->session()->token() == $token;
} public function handle($request,\Closure $next){
//todo:需要在添加了登录验证之后,取消
if($request->method() == 'POST')
{
return $next($request);
} return parent::handle($request,$next);
}
}
我们来看一下 VerifyCsrfToken.php的源码 Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php;
<?php namespace Illuminate\Foundation\Http\Middleware; use Closure;
use Carbon\Carbon;
use Illuminate\Foundation\Application;
use Symfony\Component\HttpFoundation\Cookie;
use Illuminate\Contracts\Encryption\Encrypter;
use Illuminate\Session\TokenMismatchException; class VerifyCsrfToken
{
/**
* The application instance.
*
* @var \Illuminate\Foundation\Application
*/
protected $app; /**
* The encrypter implementation.
*
* @var \Illuminate\Contracts\Encryption\Encrypter
*/
protected $encrypter; /**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = []; /**
* Create a new middleware instance.
*
* @param \Illuminate\Foundation\Application $app
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
* @return void
*/
public function __construct(Application $app, Encrypter $encrypter)
{
$this->app = $app;
$this->encrypter = $encrypter;
} /**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*
* @throws \Illuminate\Session\TokenMismatchException
*/
public function handle($request, Closure $next)
{
if (
$this->isReading($request) ||
$this->runningUnitTests() ||
$this->inExceptArray($request) ||
$this->tokensMatch($request)
) {
return $this->addCookieToResponse($request, $next($request));
} throw new TokenMismatchException;
} /**
* Determine if the HTTP request uses a ‘read’ verb.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function isReading($request)
{
return in_array($request->method(), ['HEAD', 'GET', 'OPTIONS']);
} /**
* Determine if the application is running unit tests.
*
* @return bool
*/
protected function runningUnitTests()
{
return $this->app->runningInConsole() && $this->app->runningUnitTests();
} /**
* Determine if the request has a URI that should pass through CSRF verification.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function inExceptArray($request)
{
foreach ($this->except as $except) {
if ($except !== '/') {
$except = trim($except, '/');
} if ($request->is($except)) {
return true;
}
} return false;
} /**
* Determine if the session and input CSRF tokens match.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function tokensMatch($request)
{
$token = $this->getTokenFromRequest($request); return is_string($request->session()->token()) &&
is_string($token) &&
hash_equals($request->session()->token(), $token);
} /**
* Get the CSRF token from the request.
*
* @param \Illuminate\Http\Request $request
* @return string
*/
protected function getTokenFromRequest($request)
{
$token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN'); if (! $token && $header = $request->header('X-XSRF-TOKEN')) {
$token = $this->encrypter->decrypt($header);
} return $token;
} /**
* Add the CSRF token to the response cookies.
*
* @param \Illuminate\Http\Request $request
* @param \Symfony\Component\HttpFoundation\Response $response
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function addCookieToResponse($request, $response)
{
$config = config('session'); $response->headers->setCookie(
new Cookie(
'XSRF-TOKEN', $request->session()->token(), Carbon::now()->getTimestamp() + 60 * $config['lifetime'],
$config['path'], $config['domain'], $config['secure'], false
)
); return $response;
}
}
其中app下面的VerifyCsrfToken中间件是继承源码中的那个VerifyCsrfToken类
我们项目中重写了tokensMatch方法,然后调父类的handle的时候,父类中使用的是this调用tokensMatch的,个人感觉应该最后有用的是我们重写的这个方法,如果是ajax请求的话,我们就检测$request->header('X-CSRF-TOKEN')与session中的token是否一样 否则的话,就检测 $request->input('_token')与session中的token是否一样。
本人对laravel的原理还不太了解,上面的内容如果有什么错误的话,欢迎指教。
如需转载请注明:
本文出处:http://www.cnblogs.com/zhuchenglin/p/7723997.html
laravel的csrf token 的了解及使用的更多相关文章
- sqlmap和burpsuite绕过csrf token进行SQL注入检测
利用sqlmap和burpsuite绕过csrf token进行SQL注入 转载请注明来源:http://www.cnblogs.com/phoenix--/archive/2013/04/12/30 ...
- CSRF token 无法被验证. ----Yii连接数据库后数据库错误日志报错
CSRF token 无法被验证. 我使用的是mongodb+ yii1.1 What is CSRF, please see the details here. http://en.wikiped ...
- Django后台post请求中的csrf token
使用Requests库操作自己的Django站点,post登陆admin页面返回403,serverlog显示csrf token not set. csrf token是get登陆页面时服务器放在c ...
- django rest framework csrf failed csrf token missing or incorrect
django rest framework csrf failed csrf token missing or incorrect REST_FRAMEWORK = { 'DEFAULT_AUTHEN ...
- django CSRF token missing or incorrect
django 异步请求时提示403 按照一般情况权限问题,python文件没有问题,仔细看了下response里有一句 CSRF token missing or incorrect.这个肯定是因为安 ...
- 利用sqlmap和burpsuite绕过csrf token进行SQL注入 (转)
问题:post方式的注入验证时遇到了csrf token的阻止,原因是csrf是一次性的,失效导致无法测试. 解决方案:Sqlmap配合burpsuite,以下为详细过程,参照国外牛人的blog(不过 ...
- What is the best way to handle Invalid CSRF token found in the request when session times out in Spring security
18.5.1 Timeouts One issue is that the expected CSRF token is stored in the HttpSession, so as soon a ...
- 关于django1.7.7使用ajax后出现“CSRF token missing or incorrect”问题的解决办法
最近使用Python3.3.25和django1.7.7开发公司项目,在使用ajax来post数据时,居然一直提示:403错误,原因是“CSRF token missing or incorrect” ...
- CodeIgniter中使用CSRF TOKEN的一个坑
事情的经过是这样的,一个自动化扫描工具说我的代码中存在XSS漏洞,什么是XSS不懂的朋友可以看这里 我的代码里面开启CodeIgniter框架的CSRF Token,如下: 很简单,更多详情参考CI官 ...
随机推荐
- Java身份证归属地目录树
数据库结构: web管理界面: 目录树: 视频: 应用场景:
- SpringCloud无废话入门02:Ribbon负载均衡
1.白话负载均衡 在上一篇的介绍中,我们创建了两个一模一样的服务提供者:Provider1和Provider2,然后它们提供的服务也一模一样,都叫Hello-Service.为什么一样的服务我们要部署 ...
- Java全栈程序员之06:IDEA中MAVEN项目依赖及运行
MAVEN已经成为事实上的企业项目开发中的项目类型.无论是IDEA还是Eclipse,都已经默认支持创建MAVEN项目.严格意义上来说,MAVEN不是一种新的JavaEE项目类型.它凌驾于所以的项目类 ...
- SAP传输请求自动发布
最近公司服务器做迁移,原R3 PRE需要迁到另外的地方,迁移后一段时间内,需要两套PRE环境同时运行,过一段时间后才将传输路线切换到新的PRE.在切换前,要求新PRE环境也要正常同步发布请求, ...
- 面试汇总——知道什么是同源策略吗?那怎么解决跨域问题?知道 JSONP 原理吗?
本文是面试汇总分支——知道什么是同源策略吗?那怎么解决跨域问题?知道 JSONP 原理吗?. 同源策略 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能, ...
- 解决Linux文件系统变成只读的方法
解决Linux文件系统变成只读的方法 解决方法 1.重启看是否可以修复(很多机器可以) 2.使用用 fsck – y /dev/hdc6 (/dev/hdc6指你需要修复的分区) 来修复文件系统 ...
- Java远程调用原理DEMO
1. POJO public class DemoInfo implements Serializable{ private String name; private int age; public ...
- Effective Java 第三版——82. 线程安全文档化
Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...
- 在IIS上安装 thinkphp的方法
1. 在iis安装 urlwrite 2. 安装php处理程序映射 3. 在项目中建立web.config, 键入以下内容: <?xml version="1.0" enco ...
- 通过JS页面唤醒app(安卓+ios)
var browser = { versions: function () { var u = navigator.userAgent, app = navigator.appVersion; ret ...