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官 ...
随机推荐
- selenium之 文件上传所有方法整理总结【转】
本文转自:https://blog.csdn.net/huilan_same/article/details/52439546 文件上传是所有UI自动化测试都要面对的一个头疼问题,今天博主在这里给大家 ...
- cleanmymacchinese下载链接
由于新的chinese版本还没有公开发布下载链接,所以找到如下地址 https://dl.devmate.com/com.macpaw.zh.CleanMyMac3/CleanMyMacChinese ...
- 运维笔记10 (Linux软件的安装与管理(rpm,yum))
概述:用rpm安装和管理软件(rpm解决依赖性),用yum安装与管理软件(yum解决依赖性). 1.linux的软件 linux能够说是一款改变时代的操作系统,可是一个操作系统再优秀假设没有好用的应用 ...
- 【mysql】GitHub 的 MySQL 高可用性实践分享
原文出处: shlomi-noach 译文出处:oschina GitHub 使用 MySQL 作为所有非 git 仓库数据的主要存储, 它的可用性对 GitHub 的访问操作至关重要.Gi ...
- spring拦截器中使用spring的自动注入
需要在spring的拦截器中使用自定义的服务,这要就设计到将服务注入到拦截器中.网上看的情况有两种: 1. @Configuration public class OptPermissionHandl ...
- Python 爬虫实例(7)—— 爬取 新浪军事新闻
我们打开新浪新闻,看到页面如下,首先去爬取一级 url,图片中蓝色圆圈部分 第二zh张图片,显示需要分页, 源代码: # coding:utf-8 import json import redis i ...
- 关于Java 软件工程师应该知道或掌握的技术栈
鄙人星云,今天突然想写这么一篇需要持续更新的文章,主要目的用于总结当前最流行的技术和工具,方便自己也方便他人. 更新时间:2018-10-23 09:26:19 码农职业路径图 码农入门职业路径图 J ...
- 安全工具-Sparta
Sparta是一个集端口扫描.网络扫描.服务探测以及暴力破解等多项功能于一身的工具,kali中已经预装了该工具,可直接使用. > 输入目标IP,开始扫描即可探测出开放的端口及服务 > 选中 ...
- zoj 3430 Detect the Virus(AC自己主动机)
Detect the Virus Time Limit: 2 Seconds Memory Limit: 65536 KB One day, Nobita found that his co ...
- 解决IE8下opacity属性失效问题,无法隐藏元素
解决IE8下opacity属性失效问题 由于opacity属性存在兼容性问题,所以在IE8下,用opacity来设置元素的透明度,会失效,从而导致页面的样式问题.在IE8及其更早的浏览器下,我们可 ...