欢迎各位兄弟 发布技术文章
这里的技术是共享的
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. 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. In laravel 5, there is a middleware class, Take a look at the included You can see that unless The The Okay. Time to work. We are going to add a third condition in that if statment, called Now we just need to create the This way, if I ever need to exclude a route from CSRF, I can just add it to the array here. Looks good! We've got one last step before we're done though. We need to tell Laravel to use our new And that's it you're done! 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.Middleware
How Laravel 5 Handles CSRF
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.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;
}
$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.isReading()
method just checks for "reading" verbs: HEAD, GET, OPTIONS. If one of these is being used, it skips over the CSRF check.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
$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 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. <?php namespace App\Http\Middleware;
class VerifyCsrfToken extends \Illuminate\Foundation\Http\Middleware\VerifyCsrfToken {
}
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.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;
}
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;
}
Telling Laravel about our new middleware class
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'
Closing thoughts
来自 http://www.camroncade.com/disable-csrf-for-specific-routes-laravel-5/