laravel的csrf token 的了解及使用
2017-10-24 15:57
411 查看
之前在项目中因为没有弄清楚csrf token的使用,导致发请求的话,一直请求失败,今天就一起来看一下csrf的一些东西。
1.Cross-site request forgery 跨站请求伪造,也被称为 “one click attack” 或者 session riding,通常缩写为 CSRF 或者 XSRF,是一种对网站的恶意利用。CSRF 则通过伪装来自受信任用户的请求来利用受信任的网站。
2.从字面意思就可以理解:当你访问
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方法为:
csrf的使用:
(1)在html的代码中加入:
(2)使用cookie 方式 ,将app\Http\Middleware\VerifyCsrfToken.php修改为:
使用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的使用:
在我的另一篇文章中也提到了我们那个项目中的使用过程
上面的代码都好理解,就是获取到 csrf_token令牌,然后提交,再经过中间件验证即可
下面重点来说一下 VerifyCsrfToken.php中间件
中间件的内容最开始应该只有一个 handle函数:这个是所有的都进行csrf token验证
现在项目中的这个中间件的内容
我们来看一下 VerifyCsrfToken.php的源码 Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php;
其中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
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 视图中AJAX请求、jquery-ujs异步使用DELETE请求时配置X-CSRF-TOKEN
- laravel中不使用 remember_token时退出报错,如何解决?
- Laravel - CSRF token禁用方法
- 跨域post 及 使用token防止csrf 攻击
- 使用Spring Security出现spring security Could not verify the provided CSRF token 异常
- laravel中不使用 remember_token时退出报错,如何解决?
- Laravel - CSRF token禁用方法
- 解决Laravel 5.5 header['X-CSRF-TOKEN','Authorization']请求问题
- Laravel 5 中使用 JWT(Json Web Token) 实现基于API的用户认证
- laravel post TokenMismatchException in VerifyCsrfToken.php line 53 问题解决方法
- [PHP] - Laravel - CSRF token禁用方法
- [PHP] - Laravel - CSRF token禁用方法
- Laravel (Lumen) 中使用JWT-Auth刷新token的问题
- laravel框架使用webuploader token问题
- Android中使用HttpClient获取网站CSRF token
- 关于django1.7.7使用ajax后出现“CSRF token missing or incorrect”问题的解决办法
- MVC中使用[ValidateAntiForgeryToken]防止CSRF 注入攻击
- Python-django中ajax使用POST时使用csrf_token
- 关于django1.7.7使用ajax后出现“CSRF token missing or incorrect”问题的解决办法
- [PHP] - Laravel - CSRF token禁用方法