【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里,这样势必会造成混乱,业务逻辑散落在各处,尤其对于 ...
随机推荐
- Netty(1-2)Discard Client
一.DiscardClientHandler import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelFuture; import ...
- NET Core 1.1 静态文件、路由、自定义中间件、身份验证简介
NET Core 1.1 静态文件.路由.自定义中间件.身份验证简介 概述 之前写过一篇关于<ASP.NET Core 1.0 静态文件.路由.自定义中间件.身份验证简介>的文章,主要 ...
- setTimeout() 实现程序每隔一段时间自动执行
定义和用法 setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. 语法 setTimeout(code,millisec) 参数 描述 code 必需.要调用的函数后要执行的 Ja ...
- 一个例子说明Jsp三大重要内置对象的生命周期
此处Jsp的三大内置对象指:request,session以及application.他们共有的方法:setAttribute,getAttribute,方法名和方法作用都是相同的,但是作用范围不一样 ...
- 问题:java.sql.SQLException: No value specified for parameter 1
解决方案:没有指定参数 String user = req.getParameter("user"); String pwd = req.getParameter("pw ...
- Android获取res目录下图片的uri
Uri.parse("android.resource://" + getApplicationContext().getPackageName() + "/" ...
- 初识AutoCompleteTextView
AutoCompleteTextView自动补全框继承自TextView和EditView,通过一个下拉框的形式可以补全信息. 可以通过setThreshold()方法指定用户输入多少个字符后开始显示 ...
- win7双网卡走哪个网卡路由设置
有没有软件能做这个我还真不知道.说说我的做法吧: 单位里无线是可以访问Internet的,有线是用来访问公司内部系统的. 默认的54M无线网络和100M的有线网络,系统在选择默认路由的时候肯定是选择有 ...
- 【虚拟机-磁盘管理】理解及快速测定 Azure 虚拟机的磁盘性能
随着越来越多的用户将生产系统迁移到 Azure 平台的虚拟机服务中,Azure 虚拟机的性能愈发被关注.传统的数据中心中,我们通常使用 CPU,内存,存储和网络的性能来衡量生产压力.特别是对于 IO ...
- python3操作excel02(对excel的基础操作,进行简单的封装)3
#!/usr/bin/env python# -*- coding:UTF-8 -*- import requestsfrom bs4 import BeautifulSoupfrom bs4 imp ...