删除特定路由的 Csrf 验证

4

我正在尝试为我的Laravel应用创建一个API,但是当我向某个路由发送POST请求时,Laravel默认会尝试验证CSRF令牌。所以,我想要为API路由移除这个验证。我希望保留前端请求的验证。但是,当我在app / Http / Middleware / VerifyCsrfToken.php中添加异常路由时,我遇到了以下错误:

block_exception clear_fix

这是VerifyCsrfToken.php文件。

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;

class VerifyCsrfToken extends BaseVerifier
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        //
        'log_bounces_complaints',
    ];
}

你是真的要向数据库中发布任何内容吗?还是试图从数据库中获取某些内容?如果你只是想从数据库中获取一些内容,尝试使用 get 而不是 post。这样就不会要求 csrf 验证了。 - Jilson Thomas
是的,我正在发布。这是一个日志API,所以我向数据库添加了很多信息。 - Filipe Ferminiano
解决方案是否解决了您的问题? - Jilson Thomas
@JilsonThomas 谢谢你的帮助!它成功了,但我发现 Can Celik 的答案更优雅,因为我不需要更改任何 Laravel 类。但是,还是感谢你的帮助!我已经点赞了你的答案。 - Filipe Ferminiano
2个回答

5
只需扩展VerifyCsrfToken并添加要排除的URL即可。
<?php namespace App\Http\Middleware;

use Closure;
use Illuminate\Session\TokenMismatchException;

class VerifyCsrfToken extends \Illuminate\Foundation\Http\Middleware\VerifyCsrfToken {

    protected $except_urls = [
        'your_specific_url/new_url',
        'your_specific_url/new_url_2',
        ...
    ];

    public function handle($request, Closure $next)
    {
        $regex = '#' . implode('|', $this->except_urls) . '#';

        if ($this->isReading($request) || $this->tokensMatch($request) || preg_match($regex, $request->path()))
        {
            return $this->addCookieToResponse($request, $next($request));
        }

        throw new TokenMismatchException;
    }

}

在内核中,更改新的中间件。

protected $middleware = [

    ...

    'App\Http\Middleware\VerifyCsrfToken',
];

3
根据 Laravel 文档所述:
"VerifyCsrfToken 中间件包含在 web 中间件组中,将自动验证请求输入中的令牌是否与会话中存储的令牌匹配。"
因此,如果您从特定路由中删除 "web 中间件",那么应该就可以了。
换句话说,在 routes.php 中不要将您的路由放在 web 中间件组下。
参考链接:https://laravel.com/docs/5.2/routing#csrf-protection
Route::group(['middleware' => 'web'], function () {
    // all your routes will go through CSRF check
}


// Anything outside will not go through the CRSF check unless you 
// define a middleware when constructing your controller.

Route::post('ajax', 'YourController@yourFunction');

根据我的朋友Charles的要求,您还可以将您的路由放入VerifyCrsfToken中间件的$except数组中。

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;

class VerifyCsrfToken extends BaseVerifier
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        'your_custom_route/*',
    ];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接