Ошибка «Отправка межсайтовых POST-форм запрещена» из SvelteKit в режиме разработки, когда используются origin и x-forwarded

У меня есть приложение 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

Я вижу эту переменную среды в своей среде, если я регистрирую env из import { env } from '$env/dynamic/private'; на стороне сервера. Но я все еще получаю сообщение «Отправка межсайтовых форм 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-proto и x-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 вам придется отменить эту фиксацию из-за того, что сетевой режим хоста докера не работает на Mac:
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
191
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема заключалась в том, что я был в режиме разработки (npm run dev) и что переменные среды PROTOCOL_HEADER, HOST_HEADER и ORIGIN, задокументированные в https://kit.svelte.dev/docs/adapter-node#environment-variables, работают для адаптер узла (который используется, когда вы делаете npm run build при нацеливании на NodeJS), но не для сервера разработки Vite.

Сообщение «Отправка межсайтовых POST-форм запрещена» исходит от packages/kit/src/runtime/server/respond.js , который не привязан к адаптеру узла, он запускает любой адаптер, который вы используете. Что вводит в заблуждение, так это то, что если вы будете искать это сообщение об ошибке, вы прочитаете о нем только в контексте, связанном с адаптером NodeJS, например https://kit.svelte.dev/docs/adapter-node#environment- переменные.

«Решение», о котором вы читали в этом контексте, заключается в использовании переменных среды PROTOCOL_HEADER, HOST_HEADER и ORIGIN, но они понятны только адаптеру узла. Вы можете увидеть их использование в packages/adapter-node/src/handler.js.

Когда вы запускаете приложение SvelteKit с помощью npm run dev, вы не используете адаптер NodeJS. Вы используете сервер разработки Vite, который не читает эти переменные среды. Вы можете увидеть, как этот сервер разработки устанавливает «происхождение» запроса в packages/kit/src/exports/vite/dev/index.js. Он использует только заголовок «host» запроса, но игнорирует любой «x-forwarded-host» или другие подобные заголовки.

Одним из решений является установка прокси-сервером HTTP-заголовка host. Не делайте этого в продакшене, но в режиме разработки все должно быть в порядке. Другой способ — отключить защиту CSRF в режиме разработки.

В репозитории SvelteKit на GitHub уже есть проблема по этому поводу: https://github.com/sveltejs/kit/issues/8026

Другие вопросы по теме