"Cross-site POST form submissions are forbidden" SvelteKit 在开发模式下使用原始和 x 转发时出错



我有一个SvelteKit应用程序运行在http://localhost:5173(当做本地开发)与Nginx在它前面运行在http://localhost:8057,服务一些静态文件和代理请求,必须由SvelteKit处理。

我在http://localhost:8057/login有一个登录表单,当我提交它时,我得到一个网页,只是;跨站点POST表单提交是被禁止的">

我尝试使用ORIGIN环境变量,因为跨站点POST表单提交被禁止和https://kit.svelte.dev/docs/adapter-node#environment-variables。这是我的.env文件:

ORIGIN=http://localhost:8057

如果我从服务器端的import { env } from '$env/dynamic/private';记录env,我可以在我的环境中看到这个环境变量。但是我仍然收到"禁止跨站POST表单提交">

我也尝试在启动SvelteKit(与ORIGIN=http://localhost:8057 npm run dev)时传递环境变量,但结果相同。

因为SvelteKit不记录太多,当它发送这个错误时,我可以试着猜测SvelteKit内部发生了什么,但如果在Nginx中我添加proxy_set_header Origin http://localhost:5173;然后它的工作,所以很清楚起源SvelteKit期望在这里。但是,我宁愿不这样做,因为它几乎等同于禁用CSRF保护。

然后我尝试使用https://kit.svelte.dev/docs/adapter-node#environment-variables中建议的其他方法,即使用x-forwarded-protox-forwarded-host,所以现在这是我的.env文件(如果我在应用程序中记录它们,我肯定可以看到这些值):

PROTOCOL_HEADER=x-forwarded-proto
HOST_HEADER=x-forwarded-host
ORIGIN=http://localhost:8057

和在我的Nginx配置中(替换Origin头文件可以解决所有问题的相同位置):

location @sveltekit {
proxy_pass http://localhost:5173;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
}

和我仍然收到"跨站点POST表单提交是被禁止的">。你知道我还能尝试什么吗?

如果人们想要查看或运行代码:

  • https://gitlab.com/cedricvanrompay/mazette/-/commit/bfa59261b8e5e5c95ac0bec37524a878cd815e91
  • docker-compose up --build启动Nginx
  • cd web-app; npm run dev运行SvelteKit应用程序(可能首先需要npm install)
  • 在Mac上,由于docker主机网络模式在Mac上不工作,您将不得不恢复此提交:https://gitlab.com/cedricvanrompay/mazette/-/commit/fee6fcd753b2844de307feb8acefd2898bb6efcd

问题来自于我处于开发模式(npm run dev),并且在https://kit.svelte.dev/docs/adapter-node#environment-variables中记录的PROTOCOL_HEADER,HOST_HEADERORIGIN环境变量适用于节点适配器(当您针对NodeJS执行npm run build时使用),但不适用于Vite开发服务器。

消息"禁止跨站点POST表单提交">来自packages/kit/src/runtime/server/respond.js,它与节点适配器无关,它运行您正在使用的任何适配器。误导人的是,如果你搜索这个错误消息,你只会在与NodeJS适配器相关的上下文中看到它,比如https://kit.svelte.dev/docs/adapter-node#environment-variables。

"solution"您在本文中所读到的内容是使用PROTOCOL_HEADERHOST_HEADERORIGIN环境变量,但是只有节点适配器才能理解这些变量。您可以在packages/adapter-node/src/handler.js中看到它们的使用。

当你使用npm run dev运行SvelteKit应用程序时,你没有使用NodeJS适配器。您正在使用不读取这些环境变量的Vite开发服务器。您可以看到这个开发服务器是如何设置"origin"的。packages/kit/src/exports/vite/dev/index.js中的请求。它只使用"主机"。请求的头,但忽略任何"x-forwarded-host"或其他类似的头文件

一个解决方案是让你的代理设置"主机";HTTP报头。不要在生产环境中这样做,但在开发模式下应该没问题。另一种是在dev模式下禁用CSRF保护。

SvelteKit的GitHub仓库中已经有一个问题:https://github.com/sveltejs/kit/issues/8026

相关内容

  • 没有找到相关文章

最新更新