Laravel API TokenMismatchException

6

我有一个API调用,其中包含POST数据;我们假设这是登录过程。

通过Chrome的Postman扩展程序,我发送了用户名和密码以通过POST方式登录用户。 但是我收到了以下信息:

Illuminate \ Session \ TokenMismatchException

在我的基础控制器中,我有以下代码:

    /**
     * Initializer.
     *
     * @return void
     */
    public function __construct() {
        // CSRF Protection
        $this->beforeFilter('csrf', array('on' => 'post'));

        // Layouts/Notifications
        $this->messageBag = new Illuminate\Support\MessageBag;

    }

当我删除拥有beforeFilter过滤器的行时,一切正常。 但这不是一个解决方案。 任何POST调用都会得到这个错误信息。 我知道我需要这个_token。 但是当我通过API调用时如何获取此令牌?我知道我可以在Laravel内部创建令牌,但是当我通过API从外部调用时该怎么做呢?


因为您需要将令牌作为参数发送,因为csrf过滤器将检查输入的_token字段。如果您没有发送它,则此检查将失败。 - Matt Burrow
好的。抱歉描述有些含糊不清...我知道我需要这个_token。但是当我调用API时,我该如何获取此令牌?我知道我可以在Laravel内部创建一个令牌,但是当我通过API从外部调用时,我该如何做到这一点? - goldlife
通常API用于跨站点请求。因此,您的CSRF保护是无意义的。它主要用于应用程序和网站。但是,在登录时禁用它,然后在成功登录后通过调用助手csrf_token();向用户发送csrf_token值。 - Matt Burrow
谢谢。我如何在某些请求中禁用$this->beforeFilter('csrf', array('on' => 'post'));?我在我的基本控制器的__construct函数中有这行代码。所以我希望这通常是一个前置过滤器,但在某些情况下,前置过滤器应该被禁用。这可能吗? - goldlife
3个回答

10

通常API被用于跨站点请求,因此你的CSRF保护是无意义的。

如果你不会在跨站点使用它,那么很有可能API并不是你所尝试做的事情的最佳解决方案。不过,你可以创建一个API端点来返回一个令牌。

public function getToken(){
    return Response::json(['token'=>csrf_token()]);
}

如果您想在某些方法上禁用CSRF保护,您可以使用exceptonly

$this->beforeFilter('csrf', array('on' => 'post', 
                                 'except'=>array('methodName', 'anotherMethod')
                                  ));
请参考Laravel官方文档

5

绝对不要使用这种方法。

打开VerifyCsrfToken类并定义$except属性,其中包含一个路由数组,在这些路由上不会应用CSRF保护。

以下是示例:

<?php
declare(strict_types=1);

namespace App\Http\Middleware;

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

class VerifyCsrfToken extends BaseVerifier
{
    protected $except = [
        'api/auth/login',
        'api/*', // this works as well
    ];

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure                 $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return parent::handle($request, $next);
    }
}

1

请听我说。就在30分钟前,我遇到了同样的问题。现在已经解决了。只需尝试以下步骤:

进入应用程序 -> HTTP -> 内核

打开内核文件。

您会看到: \App\Http\Middleware\VerifyCsrfToken::class,

只需使用//禁用此特定代码即可。

就这样!这将有效!

因此,您可以从API调用中删除中间件(如果需要)。


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