Laravel 5.5 Axios POST 导致 419 错误

Posted

技术标签:

【中文标题】Laravel 5.5 Axios POST 导致 419 错误【英文标题】:Laravel 5.5 Axios POST results in 419 error 【发布时间】:2018-05-06 18:23:00 【问题描述】:

我正在尝试从 Vue 向我的 Laravel API 发出 POST 请求。 X-CSRF-TOKEN 标头设置正确(我在发送到服务器的 POST 包中看到了这一点)。

路由有默认的web-middleware。

请求

Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate
Accept-Language:de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
Connection:keep-alive
Content-Length:2
Content-Type:application/json;charset=UTF-8
Host:api.xxx.local
Origin:http://manager.xxx.local
Referer:http://manager.xxx.local/location/planning/2
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/62.0.3202.94 Safari/537.36
X-CSRF-TOKEN:EAf94SFJWBhlcwzxrq7nyygrnRSmZTavrnKYHv5C
X-Requested-With:XMLHttpRequest

回应

Request URL:http://api.xxx.local/locationplanning/deleteentry/15
Request Method:POST
Status Code:419 unknown status
Remote Address:127.0.0.1:80
Referrer Policy:no-referrer-when-downgrade

错误堆栈:


    "message": "",
    "exception": "Symfony\\Component\\HttpKernel\\Exception\\HttpException",
    "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php",
    "line": 203,
    "trace": [
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php",
            "line": 175,
            "function": "prepareException",
            "class": "Illuminate\\Foundation\\Exceptions\\Handler",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/app/Exceptions/Handler.php",
            "line": 47,
            "function": "render",
            "class": "Illuminate\\Foundation\\Exceptions\\Handler",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
            "line": 83,
            "function": "render",
            "class": "App\\Exceptions\\Handler",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
            "line": 55,
            "function": "handleException",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php",
            "line": 49,
            "function": "Illuminate\\Routing\\closure",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 149,
            "function": "handle",
            "class": "Illuminate\\View\\Middleware\\ShareErrorsFromSession",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
            "line": 53,
            "function": "Illuminate\\Pipeline\\closure",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php",
            "line": 63,
            "function": "Illuminate\\Routing\\closure",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 149,
            "function": "handle",
            "class": "Illuminate\\Session\\Middleware\\StartSession",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
            "line": 53,
            "function": "Illuminate\\Pipeline\\closure",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php",
            "line": 37,
            "function": "Illuminate\\Routing\\closure",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 149,
            "function": "handle",
            "class": "Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
            "line": 53,
            "function": "Illuminate\\Pipeline\\closure",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php",
            "line": 59,
            "function": "Illuminate\\Routing\\closure",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 149,
            "function": "handle",
            "class": "Illuminate\\Cookie\\Middleware\\EncryptCookies",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
            "line": 53,
            "function": "Illuminate\\Pipeline\\closure",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/app/Http/Middleware/ForgetDomainParameter.php",
            "line": 30,
            "function": "Illuminate\\Routing\\closure",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 149,
            "function": "handle",
            "class": "App\\Http\\Middleware\\forgetDomainParameter",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
            "line": 53,
            "function": "Illuminate\\Pipeline\\closure",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 102,
            "function": "Illuminate\\Routing\\closure",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 647,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 622,
            "function": "runRouteWithinStack",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 588,
            "function": "runRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
            "line": 577,
            "function": "dispatchToRoute",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 176,
            "function": "dispatch",
            "class": "Illuminate\\Routing\\Router",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
            "line": 30,
            "function": "Illuminate\\Foundation\\Http\\closure",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
            "line": 30,
            "function": "Illuminate\\Routing\\closure",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 149,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
            "line": 53,
            "function": "Illuminate\\Pipeline\\closure",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
            "line": 30,
            "function": "Illuminate\\Routing\\closure",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 149,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
            "line": 53,
            "function": "Illuminate\\Pipeline\\closure",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php",
            "line": 27,
            "function": "Illuminate\\Routing\\closure",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 149,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
            "line": 53,
            "function": "Illuminate\\Pipeline\\closure",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php",
            "line": 46,
            "function": "Illuminate\\Routing\\closure",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 149,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
            "line": 53,
            "function": "Illuminate\\Pipeline\\closure",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
            "line": 102,
            "function": "Illuminate\\Routing\\closure",
            "class": "Illuminate\\Routing\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 151,
            "function": "then",
            "class": "Illuminate\\Pipeline\\Pipeline",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
            "line": 116,
            "function": "sendRequestThroughRouter",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        ,
        
            "file": "/Applications/XAMPP/xamppfiles/htdocs/kitchenradar/server/public/index.php",
            "line": 53,
            "function": "handle",
            "class": "Illuminate\\Foundation\\Http\\Kernel",
            "type": "->"
        
    ]

【问题讨论】:

最好检查你的 laravel.log 文件,你会得到清晰的错误信息。 @ankitpatel,日志是空的,但我得到了这个日志跟踪(见编辑) 你能确定你的路由正常吗?也许你可以用邮递员试试。 @rakete 如果我将方法更改为 GET(在路由和 axios 中),则不再有错误... 尝试在内核中停用 csrf 中间件 【参考方案1】:

如果不检查项目中的很多地方,很难看出发生了什么,所以我将列出一些可能的原因,希望它能为您指明正确的方向

第一个可能的原因是,419 http 代码是由源代码中的某些条件触发的。考虑到调用堆栈,这是极不可能的,但错误可能会被某些中间件捕获并重新创建(因此调用堆栈错误)。

另一个可能的原因,CSRF 保护。鉴于它适用于 GET 而不是 POST(请参阅 cmets),很有可能触发了 CSRF 保护并拒绝请求。要纠正这个问题,只需使用api(而不是web)中间件禁用CSRF中间件,或者将路由添加到VerifyCsrfToken类中。见How to disable some routes for CSRF validation

API 路由不需要 CSRF 保护,只有“标准”网页上的 POST 表单需要这些保护。

【讨论】:

我尝试使用api中间件和web中间件。我的问题是我需要控制器中的 Auth::user() 来检查几个操作的权限。我不认为 Passport 是一个好的解决方案,因为用户是通过普通刀片视图/控制器登录的。它不是 SPA,我只是使用 Vue2 来提高可用性并在我的刀片视图中获取一些数据。但是如何获得经过身份验证的用户?试图复制默认的 web 中间件,删除了 VerifyCsrfToken 并添加了 auth-middleware 但我总是被转发到登录页面...... 我现在调试到 VerfiyCsrfToken 中间件,发现 $request->session()->token() 在每个新的 POST 请求上重新生成...... Auth 中间件只需要 Session 中间件,不需要 CSRF 令牌。因此,如果您只有正确顺序的 Session 和 Auth,它应该可以工作。或者按照我的链接中的说明,您可以直接在 CSRF 中间件中禁用某些路由,而无需触及内核配置!【参考方案2】:

这里的问题是我们将请求从一个域发送到另一个域。 Web 前端域是 manager.xxx.local,而 API 域是 api.xxx.local

这很重要,因为 cookie 受限于它们源自的域。为安全起见,默认情况下浏览器不会将 cookie 发送到不同的域。 Laravel 将 CSRF 令牌存储在用户的 web 请求会话中,并发送一个会话 cookie 到浏览器以维护这个会话。

即使默认 Laravel 项目附带的 bootstrap.js file 通过 axios 为 AJAX 请求添加 CSRF 令牌头,我们仍然需要一个会话,以便 Laravel 可以将令牌头与服务器上的值进行比较。

我们看到 419 HTTP 状态码——通常是 TokenMismatchException 的结果——因为 API 请求没有与用户会话关联(没有会话 cookie),所以 会话中不存在 CSRF 令牌状态。因此,Laravel 认为令牌对 API 请求无效。

我们可以通过几种不同的方式来解决这个问题。现代浏览器支持Cross-Origin Resource Sharing (CORS),这在一定程度上允许我们通过 AJAX 在域之间共享 cookie。我们的服务器需要发送Access-Control-Allow-Credentials 标头:

Access-Control-Allow-Credentials: true

阅读this article on MDN 了解更多信息。 Barry vd 的 Laravel CORS 软件包。如果我们不想手动配置我们的应用程序或网络服务器,Heuvel 可以帮助进行设置。

然后,我们可以通过在XMLHttpRequest 上设置以下属性来配置 AJAX 请求以将 cookie 转发到不同的域:

xhr.withCredentials = true;

在axios中,我们可以configure withCredentials per request:

axios.get(url,  withCredentials: true );

...或将其设置为默认值:

axios.defaults.withCredentials = true;

如果我们使用 Vue Resource,我们可以设置类似的配置选项:

Vue.http.options.credentials = true;

即使我们解决了这些问题,当前的设计仍依赖服务器端会话来维护 CSRF 令牌验证的状态。传统 API 通常是无状态(没有与用户绑定的服务器端会话),并使用某种形式的访问令牌(OAuth、JWT 等)对请求进行身份验证。请注意,CSRF 令牌不是这样的令牌之一。

要获得更强大的 API 框架,请考虑使用 Laravel Passport。我们可以添加CreateFreshApiToken middleware,它会自动生成一个加密的 JWT 来传递用户 ID 和 CSRF 令牌状态,这样我们就可以构建一个无会话 API。

如果我们不想构建完整的 API,例如如果我们的 AJAX 请求只是补充服务器生成的视图,我们可能不想通过为这些请求使用单独的域来使应用程序复杂化。

注意事项:

如果我停用它,它会起作用,但我需要 Auth...。当我停用它时,Auth::user() 为空。

用户是null不是因为我们停用了 CSRF,而是因为我们没有会话开始(会话 cookie 没有发送到 API 域)。 p>

如果我将方法更改为 GET(在路由和 axios 中),则不再有错误

Laravel 不会检查 CSRF 令牌以获取语义读取数据的请求(GET、HEAD 和 OPTIONS)。它仅针对修改数据的请求(POST、PUT、DELETE 等)验证令牌。

旁注:记住这一点很重要,因为如果我们没有正确设置路由,攻击者可以伪造一个修改用户数据的 GET 请求。开发人员通常会错误地使用链接(通常使用.btn)来发出删除记录之类的简单请求:

<a href="/posts/delete/id">Delete Post</a>

恶意网站可以在页面上放置相同的链接,并且该请求会在被点击时绕过 CSRF 保护,因为浏览器会针对该链接发送 GET 请求。

【讨论】:

以上是关于Laravel 5.5 Axios POST 导致 419 错误的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Laravel 5.5 中使用 axios 获取记录

Laravel 从 5.5 升级到 5.6 到 5.7:未捕获 ReferenceError: axios is not defined

使用 API 蓝图通过 post 请求将图像提交到 Laravel 5.5

Lumen:在 routes.php 第 17 行:升级到 5.5 后调用未定义的方法 Laravel\Lumen\Application::post()。*

从 laravel 5 升级到 laravel 5.5 导致错误参数 1 传递给 App\Exceptions\Handler::report()

使用 laravel-cors 和 axios 进行 POST 的 Laravel “CSRF 令牌不匹配”