Настройка Cross-Origin Resource Sharing (CORS)

:notebook_with_decorative_cover: Это руководство how-to, которое проведёт вас через процесс настройки межсайтовой передачи ресурсов (CORS) в Discourse.

CORS — это механизм, позволяющий запрашивать множество ресурсов (например, шрифты, JavaScript и т. д.) на веб-странице с другого домена, отличного от домена, из которого был получен исходный ресурс.

Вот как настроить CORS на вашем сайте Discourse:

Требования

Перед началом работы переменная окружения DISCOURSE_ENABLE_CORS должна быть установлена в значение true, чтобы включить CORS.

Для получения помощи по этому вопросу см. Как установить переменные окружения.

:sparkles: Если вы используете размещённый сайт Discourse, этот шаг уже выполнен, и вам не нужно предпринимать дополнительных действий для его настройки.

Доступ к настройкам сайта

Перейдите в панель администратора Discourse. Оттуда перейдите на вкладку «Настройки».

Поиск настроек CORS

На вкладке «Настройки» используйте строку поиска и введите cors origin. Вы должны увидеть следующую настройку, связанную с CORS:

Эта настройка позволяет указать домены, которым разрешено отправлять межсайтовые запросы к вашему экземпляру Discourse.

Здесь следует вводить точные домены, разделяя их пробелом. Избегайте использования символа подстановки (*), так как это может создать риски безопасности.

При добавлении нескольких доменов каждый URL должен быть разделён. Например:

Сохранение изменений

После внесения необходимых изменений не забудьте нажать кнопку Сохранить изменения в нижней части страницы.

Важные замечания

Неправильная реализация CORS (межсайтовой передачи ресурсов) может создать потенциальные риски безопасности. Вот несколько вещей, о которых следует помнить при включении CORS на вашем сайте:

  • Указывайте точные домены: Использование символов подстановки (*) в конфигурации CORS может позволить любому домену взаимодействовать с вашим сервером, что представляет значительный риск безопасности. Рекомендуется указывать точные домены.
  • Минимизируйте передаваемые данные: CORS следует настраивать так, чтобы раскрывать только необходимые данные из внешних доменов, которым вы доверяете. Не рекомендуется разрешать сайтам, которыми вы не управляете, доступ через CORS.
  • Используйте HTTPS: По возможности избегайте включения не-HTTPS сайтов в вашу конфигурацию CORS, так как это может привести к передаче данных в незашифрованном виде.
2 лайка

А если используются рекламные объявления Google, возможно, лучше не трогать эту настройку :wink:

CORS (и CSP) создают определённые проблемы, так как часто сайту приходится де-факто разрешать всё, из-за чего они становятся практически бесполезными.

2 лайка

Я добавил DISCOURSE_ENABLE_CORS: "true" в секцию env файла app.yml моего сайта.
Затем я пересобрал приложение.
После этого я зашел в секцию cors_origins и добавил полный URL сайта, с которым пытаюсь настроить взаимодействие, но это всё ещё не работает.
Я создал страницу для отображения информации, когда основной сайт недоступен.
Я вставил этот JS в страницу, чтобы проверять основной сайт и перенаправлять на него, как только он снова станет доступен, но, похоже, это не работает.
Вот код:

    <script>
        function checkSiteStatus() {
            fetch('https://discourse.technospider.com', {
                method: 'HEAD',
                mode: 'cors', // Use CORS to get status code
                cache: 'no-store' // Avoid caching
            })
            .then(response => {
                console.log('Site check: Status', response.status);
                if (response.ok) { // 200-299 status codes
                    console.log('Site is up, redirecting to Discourse');
                    window.location.replace('https://discourse.technospider.com');
                } else {
                    console.log('Site is still down (status: ' + response.status + '), retrying in 20 seconds');
                    setTimeout(checkSiteStatus, 20000);
                }
            })
            .catch(error => {
                console.log('Site check: Error (likely down or CORS issue):', error.message);
                setTimeout(checkSiteStatus, 20000);
            });
        }
            
        // Start checking immediately
        checkSiteStatus();
    </script>

А вот ошибка в консоли:

[Error] Origin https://www.technospider.com is not allowed by Access-Control-Allow-Origin. Status code: 200
[Error] Fetch API cannot load https://discourse.technospider.com/ due to access control checks.
[Error] Failed to load resource: Origin https://www.technospider.com is not allowed by Access-Control-Allow-Origin. Status code: 200 (discourse.technospider.com, line 0)
[Log] Site check: Error (likely down or CORS issue): – "Load failed" (berightback, line 78)

Если у кого-то есть какие-либо идеи, буду рад узнать о них. Грок и я в тупике.

Попробуйте без двойных кавычек, иначе значение может быть интерпретировано как строка, а не как булево значение.

Сейчас жду завершения пересборки для тестирования. Если это так, то кому-то нужно исправить эту страницу:

Поскольку там показано, что значение true помещается в двойные кавычки.

Пересборка завершена, изменений нет. :frowning:

Что ж, это действительно странно… другие переменные окружения там имеют значения true без кавычек.

Это лучше использовать вместо CSP, если вы хотите, например, использовать JavaScript в сообщениях?

В настоящее время я полагался на компоненты темы или CSP для запуска JS.

С наилучшими пожеланиями,
Олле

В данном случае значение записывается в переменную окружения, которая может быть только строкой. Это не имеет значения.

Однако в целом это полезное замечание, так как вы можете получить неожиданные результаты для на первый взгляд безобидных значений:

pry(main)> YAML.load('on: yes').to_s
=> "{true=>true}"
1 лайк

Привет! Я хочу загрузить файл /latest.json с потенциально небезопасного веб-сайта, который мне не принадлежит. Возможно ли включить заголовки CORS только для определённых URL, например /latest.json, но не для таких, как /u/myname/user-menu-private-messages?