原文 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. AD7606笔记

    V1~V8共8个ADC通道: REFIN/OUT:基准电源,可选择内部(REF_SLECT=1)的或者外部的(REF_SLECT=0) VDIRVE:MCU的的VCC,2.3~5V.逻辑电平指的是需要 ...

  2. 转Keil 中使用 STM32F4xx 硬件浮点单元

    Keil 中使用 STM32F4xx 硬件浮点单元一.前言有工程师反应说 Keil 下无法使用 STM32F4xx 硬件浮点单元, 导致当运算浮点时运算时间过长,还有 一些人反应不知如何使用芯片芯片内 ...

  3. 2017 ACM Arabella Collegiate Programming Contest div2的题,部分题目写个题解

    F. Monkeying Around   维护点在多少个线段上 http://codeforces.com/gym/101350/problem/F 题意:有m个笑话,每个笑话的区间是[L, R], ...

  4. WPF (VisualChildren)可视化子元素详解

    VisualChildrenCount    的 FrameworkElement 实现始终返回 0 或 1.  如果类所要维护的可视化子元素集合的成员数可能超过 1,则这样的类必须重写此属性和 Ge ...

  5. sqlserver跟据当天年月日日期查询数据库当天数据

    select * from Client where  CONVERT(varchar(100), Cli_Datetime, 23) ='2017-11-06' 在查询之前要对表中datetime类 ...

  6. typedef int status

    是个自定义类型的语句,typedef用来定义类型的别名,status i 就相当于int i

  7. 宿主机Windows访问虚拟机Linux文件(二)

    上一篇文章中详细讲述FTP服务(基于文件传输协议的服务),本文则介绍另一种能够实现此功能Telnet(Telecommunications network 远程登陆)服务.本文介绍的telnet我常用 ...

  8. userBean-作用范围session

    package com.java1234.model; public class Student { private String name;private int age; public Strin ...

  9. 2018.2.11 JS的定时器制作

    定时器 1.定时器定义 var time = window.setInterval("执行名词",间隔时间) 关闭定时器 clearInterval(定时器名称) 倒计时定时器 s ...

  10. java中的String对象的创建及堆栈的解释

    java中的string真的是很令人头疼呢!!! 请看这里 看这里