预检响应中不允许 Laravel 前端到 Django 后端 x-csrf-token

Posted

技术标签:

【中文标题】预检响应中不允许 Laravel 前端到 Django 后端 x-csrf-token【英文标题】:Laravel frontend to Django backend x-csrf-token not allowed in preflight response 【发布时间】:2019-10-31 21:38:52 【问题描述】:

我有以 VueJS 作为前端的 Laravel 框架。此前端托管在 xampp 的本地服务器上,端口为 80,443,配置的 url 为“http://test.net”。我使用 axios 将 API 请求从 VueJS 应用程序发送到 Django 后端,在那里我安装了一个工作的 Rest 框架(可通过 Postman 访问)。后端服务器是http://127.0.0.1:8000。因为服务器不同,所以我已经安装了 django-cors-headers 包并配置了 settings.py 文件来包含这个包,并且还包含了中间件,如文档所示。

这是来自 Vue 的 axios 请求:

let url = "http://localhost:8000/leadmanager/api/lead/";
axios.get(url)
    .then(res => console.log(res.data))
    .catch(error => console.log(error));

最初我收到此错误:

从源“http://test.net”对“http://localhost:8000/leadmanager/api/lead/”处的 XMLHttpRequest 的访问已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:没有“Access-Control-Allow-Origin”标头出现在请求的资源上。

所以我检查了文档并安装了 django-cors-headers 并将 Laravel 网站的 url 包含在 CORS_ORIGIN_WHITELIST 中。

CORS_ORIGIN_WHITELIST = [
    "http://test.net"
]

执行此操作后,我得到一个不同的错误。我怀疑这是因为 Laravel 默认将 x-csrf-token 标头附加到发送的数据包中。

从源“http://test.net”访问“http://localhost:8000/leadmanager/api/lead/”处的 XMLHttpRequest 已被 CORS 策略阻止:预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段 x-csrf-token。

为了允许使用 x-csrf-tokens 的请求,我在 settings.py 中尝试了 django-cors-headers 的以下设置:

CORS_ALLOW_HEADERS = [
    'x-csrftoken'
]



CSRF_TRUSTED_ORIGINS = [
    'http://test.net'
]

那么如何配置 Django 的后端以允许来自 Laravel 的请求附加 x-csrf-headers?我想这样做,而不必修改 Laravel 的设置以不附加这些标头,因为它们是 Laravel 为减轻 CSRF 攻击而实现的安全功能。

【问题讨论】:

你把django.middleware.csrf.CsrfViewMiddleware放在你的中间件里了吗? 是的,根据 django-cors-headers 的文档,我已将其作为中间件。中间件的顺序是Cors, Common, Csrf 看看这条评论***.com/a/38842030/6682340 @Krukas 我在CSRF_TRUSTED_ORIGIN 中仅包含主机名test.net 作为指定的注释,但没有任何改变。 这可能对***.com/questions/32500073/…有帮助 【参考方案1】:

参考@bak2trak指出的https://***.com/a/32501365/10888237后,我从Chrome开发者控制台(网络标签)查看了Laravel应用程序发出的请求头,请求头是“x -csrf-token 和 x-requested-with”。所以我修改了CORS_ALLOW_HEADERS,添加了“x-requested-with”标头。

CORS_ALLOW_HEADERS = [
    'x-csrf-token',
    'x-requested-with'
]

它给出了一个不同的错误,401 [未授权],所以我删除了 REST_FRAMEWORK 的默认身份验证类。

现在请求终于可以通过了,我从 Django 后端获得了对 Laravel 的 GET 请求的适当响应。

【讨论】:

以上是关于预检响应中不允许 Laravel 前端到 Django 后端 x-csrf-token的主要内容,如果未能解决你的问题,请参考以下文章

标头 Laravel 5.3 + Angular2 中不允许 X-XSRF-TOKEN

在向外部服务器发送 ajax 调用时,Access-Control-Allow-Headers 在预检响应中不允许请求标头字段授权 [重复]

Apollo graphQL 客户端中的 CORS 异常“Access-Control-Allow-Headers 在预检响应中不允许请求标头字段内容类型”

Laravel API cors-预检响应中的Access-Control-Allow-Headers不允许请求标头字段授权[重复]

Laravel API 不允许我的前端使用 React 和 Redux 访问

跨域资源共享错误:预检响应不允许标头