原文 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的更多相关文章

  1. 【PHP】用了这么久的Laravel框架,你分析过核心架构了没

    Laravel最初的设计是为了面向MVC架构的,它可以满足如事件处理.用户身份验证等各种需求.另外它还有一个由管理数据库强力支持,用于管理模块化和可扩展性代码的软件包管理器. Laravel以其简洁. ...

  2. 【Python】Django CSRF问题

    参考资料: Django Ajax CSRF 认证:http://www.ziqiangxuetang.com/django/django-csrf.html Python Post遇到csrftok ...

  3. 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 ...

  4. 【干货】Laravel --Validate (表单验证) 使用实例

    前言 : Laravel 提供了多种方法来验证应用输入数据.默认情况下,Laravel 的控制器基类使用ValidatesRequests trait,该trait提供了便利的方法通过各种功能强大的验 ...

  5. laravel 【error】MethodNotAllowedHttpException No message

    Symfony \ Component \ HttpKernel \ Exception \ MethodNotAllowedHttpException No message 报错原因[原理]CSRF ...

  6. windows+Linux【Composer安装指定版本laravel】

    在windows下安装的方法:(php.ini中openssl.dll扩展必须打开,且版本>=5.4) 方法一:使用安装程序 这是将 Composer 安装在你机器上的最简单的方法. 下载并且运 ...

  7. Laravel --- 【转】安装调试利器 Laravel Debugbar

    [转]http://www.tuicool.com/articles/qYfmmur 1.简介 Laravel Debugbar 在 Laravel 5 中集成了 PHP Debug Bar ,用于显 ...

  8. Laravel ---【转】PhpStorm下Laravel代码智能提示

    [转]http://blog.csdn.net/pangchengyong0724/article/details/54706775 第一步:在项目的composer.json中添加如下一行 &quo ...

  9. 【php】PHP现代框架代表-Laravel框架核心技术特性

    一.php语言特点及发展现状 1.服务端脚本语言,自由度太大 ,一个业务逻辑可言写在模型里,控制器里,也可以单独封装成一个类,甚至可以嵌入到html里,这样势必会造成混乱,业务逻辑散落在各处,尤其对于 ...

随机推荐

  1. mybatis pageHelper 分页插件使用

    转载大神 https://blog.csdn.net/qq_33624284/article/details/72828977 把插件jar包导入项目(具体上篇有介绍http://blog.csdn. ...

  2. CDH5.7.2离线部署笔记

    1.部署基本信息说明: 1.1.主机信息 操作系统:选择CentOS6.7 x86-64版本 MEM:64GB,CPU: E5-2630 v3 @ 2.40GHz, DISK:2TB*4(数据节点存储 ...

  3. mysql查看各个表的大小

    information_schema 数据库,在该库中有一个 TABLES 表,这个表主要字段分别是: TABLE_SCHEMA : 数据库名 TABLE_NAME:表名 ENGINE:所使用的存储引 ...

  4. git忽略已经被提交的文件

    git忽略已经被提交的文件 git rm --cached logs/xx.log 然后更新 .gitignore 忽略掉目标文件, 最后 git commit -m "We really ...

  5. Java基础:(六)关键字

    一.final 数据: 声明数据为常量,可以是编译时常量,也可以是在运行时被初始化后不能被改变的常量. 对于基本类型,final使数值不变: 对于引用类型,final使引用不变,也就不能引用其他对象, ...

  6. 【踩坑】Nginx上配置ssl证书实现https访问

    昨天开始为域名挂上ssl证书,使得可以以https去访问服务器.按照网上所介绍的配置Nginx,然而一直访问不了网站. 第二天排查了一早上,发现不单要配置Nginx,阿里云上安全组要开启443端口,并 ...

  7. jsoup爬虫,项目实战,欢迎收看

    import com.mongodb.BasicDBObject import com.mongodb.DBCollection import org.jsoup.Jsoup import org.j ...

  8. pixhawk 固件Firmware内执行make px4fmu-v2_default 编译报错解决办法

    执行下列指令报错 make px4fmu-v2_default /bin/sh: 1: Tools/check_cmake.sh: Permission denied Makefile:44: Not ...

  9. SCCM Collection 集合获取计算机最后启动时间

    获取计算机客户端最后一次启动时间,我们可以通过多种来源获取,如活动目录组 ,而不仅仅是SCCM 收集,希望对您有所帮助,下面分享PowerShell 脚本 # 1 $CollectionName = ...

  10. 【Windows 10 v1703】解决桌面出现Removable Storage Devices的问题

    症状如下: 右键没有正常菜单,不能查看属性. 不能通过文件树找到这个文件夹. 出现原因不明. 暂时的解决方案: 右键,新建一个快捷方式.然后将快捷方式拖进垃圾桶,删除.这个文件夹将会被连带删除. 感谢 ...