【laravel】Disabling CSRF for Specific Routes - Laravel 5
原文 http://www.camroncade.com/disable-csrf-for-specific-routes-laravel-5/
Disabling CSRF for Specific Routes - Laravel 5
Update: If you are working on Laravel 5.1, there is support for this right out of the box: See this post for more information
I've been working with Laravel 5 lately, and it's great. But with a new version comes new defaults. CSRF protection for instance, is now always active with the implementation of Middleware, where in Laravel 4, it was something you "turned-on" as you needed it. In my opinion, this is a great move for Laravel, making it more secure out-of-the-box.
However, there may come a time when you want to exclude specific routes and requests from worrying about looking for a CSRF token. (In my case, I had a POST route that was used exclusively as a callback for a third-party API. It uses a different form of authentication that service renders CSRF not only unnecessary, but a hinderence. This is what I did to "disable" CSRF for specic routes.
Middleware
Laravel 5 comes with middleware. It replaces L4's filters and while they are fundamentally different, for the purpose of this guide, you can pretty much treat them as such. (For a more in-depth look at Middleware, check out Laravel 5.0 - Middleware (Filter-style))
If you're not intimately familiar with middleware, that's okay. This is also going to serve as a mini-intro to working with middleware.
How Laravel 5 Handles CSRF
In laravel 5, there is a middleware class, Illuminate\Foundation\Http\Middleware\VerifyCsrfToken with a method handle($request, Closure $closure) that is exceuted every request. It is here that it either lets the request continue on to the controller, or it throws a TokenMismatchException. We want to alter this process so that it skips CSRF protection for routes of our choosing.
Take a look at the included VerifyCsrfToken class. You can find it in the foldervendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/. The only public function is handle($request, Closure $next) and it looks like this:
public function handle($request, Closure $next)
{
if ($this->isReading($request) || $this->tokensMatch($request))
{
return $this->addCookieToResponse($request, $next($request));
}
throw new TokenMismatchException;
}
You can see that unless $this->isReading($request) OR $this->tokensMatch($request) return true, a TokenMismatchException is thrown. Otherwise, the request coninues normally. Take a look at what each of these methods do.
The isReading() method just checks for "reading" verbs: HEAD, GET, OPTIONS. If one of these is being used, it skips over the CSRF check.
Remember, CSRF is meant to prevent other websites from submitting POST data to yours, so we don't worry about it for GET requests.
The tokensMatch($request) closure is called if isReading($request) returns false. This does the work of actually deciding whether a token was included in the request, and if so, checks whether or not it matches the one stored in the session.
What we are going to do
Okay. Time to work. We are going to add a third condition in that if statment, called $this->excludedRoutes($request). But we don't want to modify the class we've been looking at. That clas is managed by composer and would get overwritten.
Because we are using namespaces, we don't have to worry about it being the same name as the one we are extending.We are going to create a new class that *extends* the VerifyCsrfToken class. I'm going to put mine in `App/Http/Middleware` and I'm going to name it `VerifyCsrfMiddleware.php`. The class, blank and extending VerifyCsrfToken looks like this:
<?php namespace App\Http\Middleware;
class VerifyCsrfToken extends \Illuminate\Foundation\Http\Middleware\VerifyCsrfToken {
}
Because we extended the Laravel default middleware class, we have access to all of it's public and protected methods. Yes, that includes `tokensMatch($request)` and `isReading($request)`. When a middleware class is called, Laravel looks for the the `handle($request, Closue $closure)` method, so we need to create that. We also want to just add an additional `OR` condition to the existing `handle($request, Closure $closure)` in the class we are extending. So go ahead and copy that into *your* blank middleware class, and let's add a `$this->excludedRoutes($request)` method that is called as the third condition. Mine now looks like this.
public function handle($request, Closure $next)
{
if ($this->isReading($request) || $this->excludedRoutes($request) || $this->tokensMatch($request))
{
return $this->addCookieToResponse($request, $next($request));
}
throw new TokenMismatchException;
}
Notice that I added `excludedRoutes($request)` as the second condition. This is because we don't need to call `$this->tokensMatch($request)` if `excludedRoutes($request)` returns true.As pointed out in the comments, copying the handle class does go against DRY. Check the comments for a cleaner alternative.
Now we just need to create the tokensMatch($request) method. I wanted an array that I could add my route-exceptions to, so this is what I came up with:
protected function excludedRoutes($request)
{
$routes = [
'some/route/path',
'users/non-protected-route'
];
foreach($routes as $route)
if ($request->is($route))
return true;
return false;
}
This way, if I ever need to exclude a route from CSRF, I can just add it to the array here.
Telling Laravel about our new middleware class
Looks good! We've got one last step before we're done though. We need to tell Laravel to use our new VerifyCsrfToken class in place of the included one. This is done in the App/Http/Kernal.php file. Go ahead and make the change to:
'App\Http\Middleware\VerifyCsrfToken'
And that's it you're done!
Closing thoughts
There are a few things to keep in mind. One, you need to be very careful anytime you do disable CSRF protection, and whether or not you actually have to disable it. Many times there is a way to include the CSRF token in the request, and if it's possible, you should probably do it. Always be careful and make sure you do have extra protections if this is what you are doing.
This is by no means the only way, nor can I imagine it being the best way, to accomplish this. If you see ways to improve this, or if you have a cleaner way of ignoring CSRF for specific routes, I'm always open to better ways of doing things and I'd love to hear about it.
【laravel】Disabling CSRF for Specific Routes - Laravel 5的更多相关文章
- 【PHP】用了这么久的Laravel框架,你分析过核心架构了没
Laravel最初的设计是为了面向MVC架构的,它可以满足如事件处理.用户身份验证等各种需求.另外它还有一个由管理数据库强力支持,用于管理模块化和可扩展性代码的软件包管理器. Laravel以其简洁. ...
- 【Python】Django CSRF问题
参考资料: Django Ajax CSRF 认证:http://www.ziqiangxuetang.com/django/django-csrf.html Python Post遇到csrftok ...
- Java EE之Hibernate异常总结【3】Disabling contextual LOB creation as createClob() method threw error java.lang.reflect.InvocationTargetException
参考文献:https://stackoverflow.com/questions/4588755/disabling-contextual-lob-creation-as-createclob-met ...
- 【干货】Laravel --Validate (表单验证) 使用实例
前言 : Laravel 提供了多种方法来验证应用输入数据.默认情况下,Laravel 的控制器基类使用ValidatesRequests trait,该trait提供了便利的方法通过各种功能强大的验 ...
- laravel 【error】MethodNotAllowedHttpException No message
Symfony \ Component \ HttpKernel \ Exception \ MethodNotAllowedHttpException No message 报错原因[原理]CSRF ...
- windows+Linux【Composer安装指定版本laravel】
在windows下安装的方法:(php.ini中openssl.dll扩展必须打开,且版本>=5.4) 方法一:使用安装程序 这是将 Composer 安装在你机器上的最简单的方法. 下载并且运 ...
- Laravel --- 【转】安装调试利器 Laravel Debugbar
[转]http://www.tuicool.com/articles/qYfmmur 1.简介 Laravel Debugbar 在 Laravel 5 中集成了 PHP Debug Bar ,用于显 ...
- Laravel ---【转】PhpStorm下Laravel代码智能提示
[转]http://blog.csdn.net/pangchengyong0724/article/details/54706775 第一步:在项目的composer.json中添加如下一行 &quo ...
- 【php】PHP现代框架代表-Laravel框架核心技术特性
一.php语言特点及发展现状 1.服务端脚本语言,自由度太大 ,一个业务逻辑可言写在模型里,控制器里,也可以单独封装成一个类,甚至可以嵌入到html里,这样势必会造成混乱,业务逻辑散落在各处,尤其对于 ...
随机推荐
- js 去除字符串空白符
var a=" 123456" varb=a.replace(/(^\s*)/g, "");
- Vue实例生命周期+vueRoter
Vue实例生命周期 vue生命周期之beforeCreate 实例创建之前除标签外,所有的vue需要的数据,事件都不存在 vue生命周期之created 实例创建之后,data和事件已经被解析到,el ...
- Django-Rest-Framework的序列化之serializers 序列化组件
Django-Rest-Framework的序列化之serializers 序列化组件 restful framework 正常的序列化 from django.http import HttpRes ...
- NETCORE MVC模块化
NETCORE MVC模块化 ASP.NETCORE MVC模块化编程 前言 记得上一篇博客中跟大家分享的是基于ASP.NETMVC5,实际也就是基于NETFRAMEWORK平台实现的这么一个轻量级插 ...
- 解读 iostat -mxd 1
#### for AWR 报告 : 建议如下: 不能随便调整db_file_multiblock_read_count 值, 取同样时间段的AWR 报告 02:00 ~ 05:00,所以db_file ...
- SpringBoot---核心---基本配置
1.[入口类和@SpringBootApplication注解] 2.[关闭特定的配置] 3.[定制Banner] 1.1 修改Banner 1.2 关闭Banner 4.SpringBoot配置文件
- fileReader 上传图片
function getImgSrc(target, callback) { if (window.FileReader) { var oPreviewImg = null, oFReader = n ...
- JavaScript中的小陷阱(不定期更新。。)
1. var scores = [1, 2, 3]; var total = 0; for (var score in scores) { total += score; } var mean = t ...
- UITableView 的一些奇淫技巧1
http://www.strongx.cn/ 感谢这位老兄 UITableView是工程开发中最经常使用到的UI控件,但是你真的了解它嘛,这里记录几点有用的但你可能并不知道的. 当我们的数据未能显示 ...
- 简述null undefined NaN的异同
1. 类型类型分析: JS中数据类型有5种:string,number,boolean,undefined,object,前四种值类型(基础数据类型),object是引用类型 var a1; //un ...