Access-Control-Allow-Origin: * убирает CORS ошибку за десять секунд и заодно открывает API любому сайту в интернете, включая тот, что читает чужие сессии через ваш же бэкенд. Правильная настройка CORS в AI проекте строится не на звездочке в заголовке…
400 000+ органических переходов за 3 месяца. Со-основатель GoBanana (231K пользователей, 12+ млн ₽ без рекламы) и NeuroScribe (65K пользователей). SEO/GEO-стратегии для AI-поисковиков, 1 700+ единиц контента, 17+ реализованных стратегий.
Об авторе →Claude Code: новый CLI-агент от Anthropic
Anthropic выпустила Claude Code — терминальный AI-агент для разработчиков. Инструмент работает прямо в командной строке и умеет писать, редактировать и запускать код.
Zcode AI: Полный гид по визуальному интерфейсу для Claude Code и AI-агентов
Узнайте, как использовать Zcode для управления Claude Code, Gemini и Codex в едином GUI. Настройка провайдеров, MCP-серверов и визуальный вайбкодинг.
YouTube-канал с монетизацией из любой точки мира: Пошаговый гайд 2026
Инструкция по созданию YouTube-канала: обход блокировок SMS, настройка расширенных функций через виртуальные номера и правила безопасности для монетизации.
Windsurf Code Maps: Как глубоко понимать архитектуру проекта перед написанием кода
Полный гайд по Windsurf Code Maps, модели Sway 1.5 и Sway Grep. Узнайте, как визуализировать архитектуру кода и ускорить разработку в 13 раз.
Vk Fast Cash Strategy
Аудитория ВКонтакте — это те же люди, что и в Instagram, но 'социальный контракт' площадки другой. Если Instagram — это 'дорогой ресторан' с демонстрацией успеха, то VK — это 'душевная шашлычная'. Здесь не работает глянцевый 'успешный успех
Access-Control-Allow-Origin: * убирает CORS ошибку за десять секунд и заодно открывает API любому сайту в интернете, включая тот, что читает чужие сессии через ваш же бэкенд. Правильная настройка CORS в AI проекте строится не на звездочке в заголовке, а на allowlist конкретных origin. Ниже разберем, чем опасен wildcard для API с авторизацией, как работает preflight запрос и как задать allowlist в Node.js и Python на живом коде.
Access-Control-Allow-Origin: * открывает API любому сайту и несовместим с cookies и авторизацией. Рабочая настройка CORS для AI проекта — allowlist origin плюс проверка preflight OPTIONS запроса на сервере. Ниже код для Node.js на Express, Python на FastAPI, разбор частых ошибок и таблица подходов к allowlist.
CORS — это правило браузера, а не сервера. Он решает, может ли JavaScript с одного origin прочитать ответ от API на другом origin.

Факт: origin — это связка протокол плюс хост плюс порт. Смена любого из трех дает новый origin: localhost:3000 и localhost:8000 для браузера это два разных сайта, даже на одной машине разработчика.
Same-Origin Policy придумали не ради занудства. Она блокирует сценарий, когда пользователь залогинен в банке в одной вкладке, а вредоносная страница в другой тихо шлет запрос на bank.com и получает доступ к сессии через cookies. CORS не отменяет это правило, а дает серверу управляемый способ сделать исключение для origin, которым он доверяет.
Для AI проекта это не абстракция. Если бэкенд дергает Claude или OpenRouter API и хранит ключи на сервере, а фронт стучится в ваш же эндпоинт с токеном пользователя, каждый заголовок CORS решает, кто еще может прочитать этот ответ из браузера.
Wildcard в Access-Control-Allow-Origin разрешает читать ответ любому сайту. Для публичного API без данных пользователя это нормально, для эндпоинта с cookies или токенами это уже риск.
Факт: спецификация Fetch напрямую запрещает комбинацию Access-Control-Allow-Origin: * вместе с Access-Control-Allow-Credentials: true. Браузер просто отклонит такой ответ, и это не баг, а осознанное ограничение против CSRF.
Разработчик меняет JWT в заголовке Authorization на сессионные cookies, ставит credentials: 'include' на фронте и получает CORS ошибку там, где вчера все работало. Причина не в коде, а в том, что звездочка и credentials несовместимы по спецификации. Единственный рабочий вариант с cookies: конкретный origin в ответе, а не wildcard.
Даже без cookies звездочка остается риском для AI API. Любой сайт сможет дергать эндпоинт от лица браузера пользователя, читать ответы с персональными данными или расходовать платные токены LLM-провайдера через чужой ключ на бэкенде.

| Подход | Access-Control-Allow-Origin | Работает с credentials | Подходит для |
|---|---|---|---|
| Wildcard | * | Нет | Публичный API без авторизации, статический контент |
| Allowlist | конкретный origin из списка | Да | API с cookies, JWT, платными LLM-запросами |
| Динамическое отражение origin | origin из запроса, если он в списке | Да | Мультидоменные проекты, staging и продакшен вместе |
Preflight — это отдельный OPTIONS запрос, который браузер шлет перед основным, чтобы спросить у сервера разрешение. Разработчик его не пишет, он появляется сам.
Факт: запрос остается «простым» и идет без preflight, только если метод GET, HEAD или POST, а заголовки из небольшого стандартного набора. Content-Type: application/json в этот список не входит, поэтому почти любой JSON-запрос к AI API запускает preflight.
Как только запрос выходит за эти рамки, например добавляется заголовок Authorization или метод меняется на PUT, браузер сначала отправляет OPTIONS с origin, методом и списком заголовков, которые собирается использовать. Сервер отвечает любым 2xx статусом и списком того, что разрешает. Только после этого уходит настоящий запрос.

Если на бэкенде нет обработчика для OPTIONS, сервер вернет 404, preflight провалится и реальный запрос вообще не уйдет. В консоли браузера при этом появится обобщенная CORS ошибка, а не «404 на OPTIONS». Именно это сбивает разработчиков с толку на диагностике.
В Node.js allowlist собирается через middleware cors с функцией origin, которая сверяет входящий origin со списком разрешенных.
Факт: пакет cors для Express — самый популярный способ настройки CORS в Node.js экосистеме. Без него нужно вручную выставлять пять-шесть заголовков на каждый ответ и отдельно обрабатывать OPTIONS.
Логика простая: держим массив разрешенных origin, в функции origin сверяем запрос со списком и вызываем callback с true или false. Для продакшена в список идут только реальные домены, localhost добавляется отдельной веткой для дев-окружения.

const express = require('express');
const cors = require('cors');
const allowedOrigins = [
'https://vibecoderz.ru',
'https://app.vibecoderz.ru',
...(process.env.NODE_ENV !== 'production' ? ['http://localhost:3000'] : [])
];
const corsOptions = {
origin(origin, callback) {
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error(`Origin ${origin} не в allowlist`));
}
},
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
};
const app = express();
app.use(cors(corsOptions));Проверка !origin нужна для запросов без заголовка Origin, например от серверных клиентов или curl. Если API дергают только из браузера, эту строку можно убрать и требовать origin всегда.
В FastAPI allowlist задается через CORSMiddleware одним блоком конфигурации без ручной обработки OPTIONS.
Факт: CORSMiddleware берет на себя и простые запросы, и preflight. Разработчику остается только перечислить origin, методы и заголовки, а не писать обработчик для каждого случая руками.
Схема повторяет Node.js: список доверенных origin, флаг credentials и явный перечень методов и заголовков вместо wildcard. Для Flask логика та же через пакет flask-cors, только конфигурация задается декоратором или объектом CORS на приложении.

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
allowed_origins = [
"https://vibecoderz.ru",
"https://app.vibecoderz.ru",
]
app.add_middleware(
CORSMiddleware,
allow_origins=allowed_origins,
allow_credentials=True,
allow_methods=["GET", "POST", "PUT", "DELETE"],
allow_headers=["Content-Type", "Authorization"],
)Один нюанс из спецификации переносится в Python один к одному: allow_origins=["*"] вместе с allow_credentials=TrueFastAPI даже не запустит без предупреждения в логах. Комбинация ломается на уровне браузера, а не фреймворка, так что обходных путей тут нет и не должно быть.
Максим: «Мог просто засесть до пяти утра и править одну функцию, которая не работала. В моменте я уже испотел, хотелось все закрыть. Но понимал, что это можно решить, и нужно решить, чтобы идти дальше.»
С CORS та же история: ошибка выглядит как одна строчка в консоли, а причина обычно в OPTIONS-обработчике или в сочетании заголовков, до которого нужно докопаться, а не гуглить готовые заголовки и вставлять наугад.
Большинство CORS-инцидентов сводится к пяти повторяющимся ошибкам, а не к экзотическим багам.
Факт: самая частая связка — wildcard плюс credentials, которую браузер просто отклоняет. Вторая по частоте — забытый обработчик OPTIONS, из-за которого preflight падает с 404 еще до того, как сервер увидел настоящий запрос.

| Ошибка | Что происходит | Как избежать |
|---|---|---|
| * вместе с credentials: true | Браузер блокирует ответ целиком | Всегда конкретный origin при работе с cookies или токенами |
| Нет обработчика OPTIONS | Preflight падает с 404, запрос не уходит | Подключить cors/CORSMiddleware, они закрывают OPTIONS сами |
| Забыт кастомный заголовок в Allow-Headers | JSON-запрос с Authorization падает на preflight | Явно перечислять все заголовки, которые шлет фронт |
| Origin отражается без Vary: Origin за CDN | CDN кеширует ответ для одного origin и отдает его другому | Добавлять заголовок Vary: Origin при динамическом allowlist |
| CORS воспринимается как замена авторизации | Прямой запрос curl или сервер-сервер обходит CORS полностью | Проверять токен и права на каждом эндпоинте отдельно от CORS |
Последний пункт стоит отдельного внимания. CORS работает только в браузере и защищает от чтения ответа скриптом с чужого сайта. Постман, curl, серверный код другого сервиса или скрипт злоумышленника, который бьет напрямую в API, к CORS вообще не имеют отношения, потому что там нет браузера и понятия origin. Единственная настоящая защита API с LLM-ключами внутри, это проверка авторизации на каждом запросе, а не заголовок CORS.

Токен в заголовке Authorization не требует credentials: true и wildcard-совместим. Cookies требуют явного allowlist и Access-Control-Allow-Credentials: true на каждом ответе.

Если фронт и бэкенд AI-продукта живут на разных доменах, токен в Authorization обычно проще в поддержке: не нужен credentials: 'include' на фронте, не нужен wildcard-запрет на бэкенде. Cookies удобнее для UX, автообновление сессии без ручного рефреша токена, но платят за это конфигурацией allowlist без права на ошибку.
Для мобильных клиентов и server-to-server интеграций origin вообще не приходит, поэтому там CORS не участвует, а роль защиты играет только API-ключ или подпись запроса.
Диагностика начинается не с консоли, а с вкладки Network: там видно, был ли preflight, какой статус вернул OPTIONS и что реально прислал сервер.

Консоль браузера сообщает только «CORS error» без деталей, была ли это 404 на OPTIONS или отсутствующий Access-Control-Allow-Origin. Вкладка Network показывает сам OPTIONS-запрос отдельной строкой, его статус и заголовки ответа. Если preflight вообще не запустился, значит запрос простой, и проблема в Access-Control-Allow-Origin на основном ответе. Если запустился и упал, смотреть нужно в Allow-Methods и Allow-Headers preflight-ответа, а не в основной запрос.
Проверка через curl или Postman ничего не скажет про CORS: оба инструмента работают без браузера и без origin, поэтому ошибка там просто не появится, даже если конфигурация на сервере сломана для реальных пользователей.
Allowlist точнее wildcard и единственный рабочий вариант при cookies или платных LLM-запросах через бэкенд. Список origin явно фиксирует, кто имеет доступ, а Access-Control-Allow-Credentials работает предсказуемо, без риска случайно открыть API всем при следующем деплое.
Минус в поддержке: каждый новый поддомен, preview-деплой на Vercel или Railway, staging-окружение требует ручного добавления в список. Для проектов с частыми превью-ссылками удобнее динамическое отражение origin из allowlist, как в примере выше с функцией origin в Node.js, но с обязательным заголовком Vary: Origin, если ответ проходит через CDN.

| Сценарий | Рекомендация |
|---|---|
| Публичный AI API без пользовательских данных | Wildcard допустим, credentials не используются |
| SaaS с личным кабинетом и cookies | Только allowlist, Allow-Credentials: true |
| Несколько окружений: prod, staging, preview | Динамическое отражение origin из списка плюс Vary: Origin |
| Мобильное приложение или интеграция сервер-сервер | CORS не требуется, защита через API-ключ |
Каталог AI-инструментов на vibecoderz.ru/ide собирает IDE и агентов, с которыми удобно писать и проверять такой backend-код, а Claude Code и Cursor хорошо разбирают существующую конфигурацию CORS и подсказывают, какой заголовок пропущен, если вставить им лог ошибки из Network.
CORS ошибка есть в браузере, но в Postman все работает, что не так? Ничего не сломано на сервере. Postman не браузер, у него нет origin и Same-Origin Policy, поэтому CORS там просто не участвует. Смотреть проблему нужно только через вкладку Network в браузере.
Можно ли ставить Access-Control-Allow-Origin: * если у API нет авторизации? Да, для полностью публичных данных без cookies и токенов wildcard безопасен. Как только появляется авторизация или платный LLM-ключ на бэкенде, переходите на allowlist.
Почему Access-Control-Allow-Credentials не работает вместе с wildcard? Так задано в спецификации Fetch. Комбинация звездочки и credentials позволила бы любому сайту читать авторизованные ответы, поэтому браузер блокирует такой ответ целиком.
Как разрешить сразу несколько origin в одном CORS-заголовке? Заголовок принимает только одно значение или звездочку, перечислить домены через запятую нельзя. Решение — проверять входящий origin на сервере против allowlist и подставлять в ответ именно его.
Preflight запрос падает с 404, что делать? Значит на бэкенде нет обработчика OPTIONS для этого маршрута. Библиотеки вроде cors для Express или CORSMiddleware для FastAPI закрывают это автоматически, вручную писать OPTIONS-роут не нужно.
Защищает ли CORS от кражи API-ключа? Нет. CORS ограничивает только чтение ответа из браузера чужим сайтом. Ключ, который лежит на клиенте или передается напрямую curl-запросом, CORS никак не прикрывает, нужна отдельная проверка авторизации на сервере.
Нужно ли настраивать CORS для мобильного приложения? Обычно нет. Мобильные клиенты не отправляют заголовок Origin и работают вне Same-Origin Policy, поэтому CORS-настройка бэкенда на них не влияет.
Origin — связка протокол, хост и порт. Меняется любой из трех, origin считается другим.
CORS — Cross-Origin Resource Sharing, механизм браузера, которым сервер разрешает конкретным origin читать свои ответы.
Preflight запрос — служебный OPTIONS-запрос, который браузер шлет перед «непростым» запросом, чтобы спросить разрешение у сервера.
Same-Origin Policy — правило браузера по умолчанию: скрипт с одного origin не может читать ответы с другого.
CSRF — атака, при которой чужая страница использует cookies пользователя для запроса к другому сайту от его имени.
Allowlist — список конкретных origin, которым явно разрешен доступ, в противовес открытому wildcard.
Credentials — cookies, HTTP-авторизация или клиентские сертификаты, которые браузер прикрепляет к запросу.
Если после настройки CORS остаются вопросы по архитектуре AI-бэкенда, конкретный разбор своей конфигурации можно получить на консультации у Максима. Для команд, которые закрывают такие задачи на потоке, в каталоге агентов есть готовая роль DevOps-агента под инфраструктурные и security-задачи AI-проекта.