【问题标题】:Laravel 5.2.31 TokenMismatchException in VerifyCsrfToken.php via HttpRequester通过 HttpRequester 在 VerifyCsrfToken.php 中的 Laravel 5.2.31 TokenMismatchException
【发布时间】:2017-08-31 11:48:30
【问题描述】:

我在“飞行”控制器中有这个方法:

    /**
 * Store a newly created resource in storage.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
public function store(Request $request)
{
    $arrivalDateTime = $request -> input('arrival.datetime');

    return $arrivalDateTime;
}

还有路线:

Route::resource('api/v1/flights', v1\FlightController::class, ['except' => ['create', 'edit']]);

我尝试使用 HttpRequester 向该地址发出 POST 请求:

http://localhost:8000/api/v1/flights

有了这个内容:

{
"flightNumber":"JWM12345",
"status":"ontime",
"arrival": {
    "datetime":"2016-04-10 22:34:01",
    "iataCode":"A57"
},
"departure": {
    "datetime":"2016-04-10 21:34:01",
    "iataCode":"9C1"
}}

我将 Content Type 设置为“application/json”,然后我提交请求并收到此错误:

VerifyCsrfToken.php 第 67 行中的 TokenMismatchException:

in VerifyCsrfToken.php line 67
at VerifyCsrfToken->handle(object(Request), object(Closure))
at call_user_func_array(array(object(VerifyCsrfToken), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in ShareErrorsFromSession.php line 49
at ShareErrorsFromSession->handle(object(Request), object(Closure))
at call_user_func_array(array(object(ShareErrorsFromSession), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in StartSession.php line 64
at StartSession->handle(object(Request), object(Closure))
at call_user_func_array(array(object(StartSession), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in AddQueuedCookiesToResponse.php line 37
at AddQueuedCookiesToResponse->handle(object(Request), object(Closure))
at call_user_func_array(array(object(AddQueuedCookiesToResponse), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in EncryptCookies.php line 59
at EncryptCookies->handle(object(Request), object(Closure))
at call_user_func_array(array(object(EncryptCookies), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
at Pipeline->then(object(Closure)) in Router.php line 726
at Router->runRouteWithinStack(object(Route), object(Request)) in Router.php line 699
at Router->dispatchToRoute(object(Request)) in Router.php line 675
at Router->dispatch(object(Request)) in Kernel.php line 246
at Kernel->Illuminate\Foundation\Http\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 52
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in CheckForMaintenanceMode.php line 44
at CheckForMaintenanceMode->handle(object(Request), object(Closure))
at call_user_func_array(array(object(CheckForMaintenanceMode), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 136
at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 32
at Pipeline->Illuminate\Routing\{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
at Pipeline->then(object(Closure)) in Kernel.php line 132
at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 99
at Kernel->handle(object(Request)) in index.php line 54
at require_once('/home/dendi/Documents/GitProjects/airview/public/index.php') in server.php line 21

我应该怎么做才能使我的请求成功?

【问题讨论】:

  • _token 在 POST、PUT、DELETE 方法中是必需的。如果您默认使用 Web 中间件。
  • 在请求正文中发送_token
  • HttpRequester、Header、Parameter中有选项。我尝试使用名称“_token”和值“{{ csrf_token() }}”,但仍然遇到相同的错误。
  • 值应该是一个字母数字字符串,例如n2s68OPSzaMVYyiFvvDhlRwvFF55zDwKaQPjX8AS。可以通过csrf_token方法获取。

标签: php laravel api laravel-5.2


【解决方案1】:

_token 在 POST、PUT、DELETE 方法中是必需的。如果您默认使用 Web 中间件。

要获取令牌,您可以创建一个使用csrf_token() 函数获取令牌并返回它的路由。 向该路由发出请求以获取类似于 n2s68OPSzaMVYyiFvvDhlRwvFF55zDwKaQPjX8AS 的令牌并将其放入请求正文中,如

 {
   "_token":"n2s68OPSzaMVYyiFvvDhlRwvFF55zDwKaQPjX8AS",
   ...
 } 

并提出请求。

如果您不想在某些路由上使用 csrf 验证,请在我使用此命名空间 App\Http\Middleware 的任何命名空间中创建一个像这样的新 VerifyCsrfToken

现在在$except数组中添加你不想被csrf令牌验证的路由。

<?php

namespace App\Http\Middleware;

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

class VerifyCsrfToken extends BaseVerifier {

     protected $except = [
        'api/v1/flights'
    ];

 }

现在将其替换为kernel.php

protected $middleware = [
    'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
    'Illuminate\Cookie\Middleware\EncryptCookies',
    'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
    'Illuminate\Session\Middleware\StartSession',
    'Illuminate\View\Middleware\ShareErrorsFromSession',
    'Illuminate\Foundation\Http\Middleware\VerifyCsrfToken', // <-- this
 ]

有了这个

protected $middleware = [
    'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
    'Illuminate\Cookie\Middleware\EncryptCookies',
    'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
    'Illuminate\Session\Middleware\StartSession',
    'Illuminate\View\Middleware\ShareErrorsFromSession',
    'App\Http\Middleware\VerifyCsrfToken', // <-- this
 ]

希望这会有所帮助:)

【讨论】:

  • 我现在使用第二种解决方案,它的工作原理。谢谢
【解决方案2】:

非常容易修复 - 只需添加以下行:

{{ csrf_field() }}

在您的表单中。它将创建一个用于 CSRF 保护的隐藏字段,并且错误将消失。

【讨论】:

  • 我使用名为 'HttpRequester' 的 API 调试器,类似于 Postman。如何以及在何处添加 {{ csrf_field() }} ?
  • 就在你的表单里面,所以
【解决方案3】:

我认为你应该升级到 Laravel 5.4,在 5.4 中路由文件夹中有一个名为 api.php 的不同文件,你可以在那里编写你的 api 路由,可以通过“api/ruote_name”访问。

干杯。

【讨论】:

  • 谢谢,如果升级到 5.4 可能会起作用。但是我在 laravel 更新后遇到了问题,并且在 5.2 中仍然很舒服。
  • 您可以尝试一件事-您将请求正文中的数据以原始json格式发送,然后我希望您的问题将得到解决。通常,如果 Content-type 是 application/json 并且您在表单正文中发送数据,则会发生令牌不匹配。您可以将 Content-Type 设置为 application/json 并将正文中的数据设置为原始 json。
【解决方案4】:

关于什么是 CSRF 令牌,我认为您应该阅读 this excellent answer。 Laravel 使用名为 VerifyCsrfToken 的中间件验证这些请求。

如果您想在 Laravel 5.2 中禁用此功能,请打开 App/Http/Kernel.php

protected $middleware = [
        'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
        'Illuminate\Cookie\Middleware\EncryptCookies',
        'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
        'Illuminate\Session\Middleware\StartSession',
        'Illuminate\View\Middleware\ShareErrorsFromSession',
        'Illuminate\Foundation\Http\Middleware\VerifyCsrfToken',
]

并从中间件数组中删除 'Illuminate\Foundation\Http\Middleware\VerifyCsrfToken'

【讨论】:

    猜你喜欢
    • 2016-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-20
    • 1970-01-01
    • 2017-07-29
    • 2016-12-23
    相关资源
    最近更新 更多