Laravel 5.5 Axios POST导致419错误 [英] Laravel 5.5 Axios POST results in 419 error

查看:136
本文介绍了Laravel 5.5 Axios POST导致419错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从Vue对我的Laravel API进行POST请求. X-CSRF-TOKEN 标头设置正确(我在发送到服务器的POST程序包中看到了此信息).

I am trying to make a POST-request to my Laravel API from Vue. The X-CSRF-TOKEN header is set correctly (I see this in the POST-package sent to the server).

该路由具有默认的 web -中间件.

The route has the default 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": "->"
        }
    ]
}

推荐答案

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

The problem here is that we're sending the request from one domain to another. The web frontend domain is manager.xxx.local while the API domain is api.xxx.local.

这很重要,因为cookie受限于它们所来自的域.为了安全起见,浏览器默认不会将Cookie发送到其他域.Laravel将CSRF令牌存储在用于Web请求的用户会话中,并向浏览器发送会话cookie 来维护该会话.

This is important because cookies are constrained to the domain they originate from. For security, the browser will not send cookies to a different domain by default. Laravel stores the CSRF token in the user's session for web requests and sends a session cookie to the browser to maintain this session.

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

Even though the bootstrap.js file, which ships with a default Laravel project, adds the CSRF token header for AJAX requests through axios, we still need a session so that Laravel can compare the token header to the value on the server.

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

We see the 419 HTTP status code—usually the result of a TokenMismatchException—because the API request is not associated with a user session (no session cookie), so no CSRF token state exists in the session. Because of this, Laravel considers the token invalid for the API request.

我们可以通过两种不同的方式解决此问题.现代浏览器支持跨源资源共享(CORS),这在一定程度上允许我们通过AJAX在域之间共享Cookie.我们的服务器需要发送 Access-Control-Allow-Credentials 标头:

We can solve this problem a couple of different ways. Modern browsers support Cross-Origin Resource Sharing (CORS) which, in part, allows us to share cookies between domains via AJAX. Our server needs to send the Access-Control-Allow-Credentials header:

Access-Control-Allow-Credentials: true

有关详细信息,请阅读有关MDN的文章.Barry vd的 Laravel CORS 软件包.如果我们不想手动配置我们的应用程序或Web服务器,Heuvel可以帮助您进行设置.

Read this article on MDN for more information. The Laravel CORS package by Barry vd. Heuvel can help set this up if we don't want to manually configure our application or webserver.

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

Then, we can configure AJAX requests to forward cookies to a different domain by setting the following property on the XMLHttpRequest:

xhr.withCredentials = true;

在axios中,我们可以为每个请求配置 withCredentials :

In axios, we can configure withCredentials per request:

axios.get(url, { withCredentials: true });

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

...or set it as the default:

axios.defaults.withCredentials = true;

如果我们使用的是Vue资源,则可以设置类似的配置选项:

If we're using Vue Resource, we can set a similar configuration option:

Vue.http.options.credentials = true;

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

Even when we fix these issues, the current design relies on server-side sessions to maintain state for the CSRF token validation. Conventional APIs are typically stateless (no server-side session tied to a user) and authenticate requests using some form of access token (OAuth, JWT, etc.). Note that the CSRF token is not one such token.

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

For a more robust API framework, consider using Laravel Passport. We can add the CreateFreshApiToken middleware that automatically generates an encrypted JWT to pass the user ID and CSRF token state so that we can build a sessionless API.

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

If we don't want to build a full API, such as if our AJAX requests just supplement the views generated by the server, we may not want to complicate the application by using a separate domain for these requests.

注释:

如果我停用它,但是我需要Auth ...,它可以工作.当我停用它时,Auth :: user()为null.

It works if I deactivate it but I need the Auth.... Auth::user() is null when I deactivate it.

用户是 null not ,因为我们停用了CSRF,但是因为我们没有会话开始(会话cookie没有发送到API域).

The user is null not because we deactivated CSRF, but because we don't have a session to begin with (the session cookie wasn't sent to the API domain).

如果我将方法更改为GET(在路线和axios中),就不会再出现错误了

If I change the method to GET (in routes and axios) there is no error anymore

Laravel不检查CSRF令牌是否有语义上读取数据(GET,HEAD和OPTIONS)的请求.它仅针对修改数据(POST,PUT,DELETE等)的请求验证令牌.

Laravel does not check the CSRF token for requests that semantically read data (GET, HEAD, and OPTIONS). It verifies the token only for requests that modify data (POST, PUT, DELETE, etc.).

附带说明:记住这一点很重要,因为如果我们没有适当地设置路由,攻击者就会伪造一个GET请求来修改用户的数据.开发人员通常会犯一个错误,即使用链接(通常带有 .btn )来进行简单的请求,例如删除记录:

Side note: this is important to remember because an attacker can forge a GET request that modifies a user's data if we don't set up our routes appropriately. Developers commonly make the mistake of using a link (often with .btn) to make a simple request like deleting a record:

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

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

A malicious site can place the same link on a page and the request will bypass CSRF protection when clicked because the browser sends a GET request for the link.

这篇关于Laravel 5.5 Axios POST导致419错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆