Сеопфатен водич за решавање на проблемот со неиспраќање колачиња во барањата помеѓу домени (CORS)

Ако сте се сретнале со сценарио каде серверот правилно поставува колаче (видливо во одговорот на прелистувачот), но во следните барања, прелистувачот не го враќа тоа колаче до серверот, овој водич е за вас. Овој проблем скоро секогаш се јавува кога фронтендот и бекендот на вашиот проект се на два различни домени или порти — на пример, фронтенд на app.example.com и API на api.example.com.

Зошто се случува ова?

Модерните прелистувачи наметнуваат две строги безбедносни политики за да спречат CSRF напади и кражба на сесии:

  1. CORS политика: Стандардно, прелистувачот не дозволува барањата помеѓу домени да вклучуваат акредитиви (како колачиња) освен ако серверот експлицитно не дозволи тоа.
  2. SameSite политика: Од Chrome 80 па натаму, колачињата стандардно се третираат со однесување SameSite=Lax, што значи дека нема да се испраќаат во барања помеѓу домени освен ако експлицитно не се дефинирани со SameSite=None.

Важната точка е дека за да се реши овој проблем, и клиентската и серверската страна мора правилно да се конфигурираат. Само модифицирање на една страна не е доволно.

Чекор 1: Правилна конфигурација на серверот

Три златни правила на серверска страна

Правило 1 — Овозможете акредитиви: Заглавјето на одговорот на серверот мора да ја содржи следната вредност:

Access-Control-Allow-Credentials: true

Правило 2 — Без џокер знак: Кога акредитивите се овозможени, не можете да го користите џокер знакот * во заглавјето Access-Control-Allow-Origin. Мора точно да ја наведете целосната адреса на доменот на фронтендот:

Access-Control-Allow-Origin: https://app.example.com

Правило 3 — Атрибути на колачето: Колачето мора да се постави со два атрибута: SameSite=None и Secure. Без овие два атрибута, прелистувачот ќе го складира колачето, но никогаш нема да го испрати во барања помеѓу домени.

Пример код во Node.js (Express)

const express = require('express');
const cors = require('cors');

const app = express();

app.use(cors({
  origin: 'https://app.example.com', // Точен домен на фронтендот, без /
  credentials: true
}));

app.post('/login', (req, res) => {
  res.cookie('session_token', 'abc123', {
    httpOnly: true,   // Спречува JavaScript пристап до колачето
    secure: true,     // Се испраќа само преку HTTPS
    sameSite: 'none', // Овозможува испраќање во Cross-Origin барања
    maxAge: 24 * 60 * 60 * 1000
  });
  res.json({ message: 'Најавувањето беше успешно' });
});

Пример код во PHP

<?php
// Наведете го точниот домен на фронтендот, не *
header("Access-Control-Allow-Origin: https://app.example.com");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");

// Одговор на Preflight барање
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(204);
    exit;
}

// Поставување на колачето со потребните атрибути
setcookie('session_token', 'abc123', [
    'expires'  => time() + 86400,
    'path'     => '/',
    'secure'   => true,      // Задолжително
    'httponly' => true,
    'samesite' => 'None'     // Задолжително за Cross-Origin
]);

Забелешка: Ако користите Laravel, поставете го supports_credentials на true во датотеката config/cors.php и додајте го доменот на фронтендот во низата allowed_origins.

Чекор 2: Правилна конфигурација на клиентот (фронтендот)

Дури и со целосна конфигурација на серверот, прелистувачот сеуште нема да испраќа колачиња освен ако на клиентска страна експлицитно не декларирате дека ова барање е "со акредитиви".

Користење на Fetch API

fetch('https://api.example.com/user/profile', {
  method: 'GET',
  credentials: 'include'  // Оваа линија е клучот за решавање на проблемот
})
  .then(res => res.json())
  .then(data => console.log(data));

Користење на Axios

// За специфично барање
axios.get('https://api.example.com/user/profile', {
  withCredentials: true
});

// Или глобално за целиот проект
axios.defaults.withCredentials = true;

Контролна листа за решавање на проблеми

Ако проблемот продолжи и по примена на горенаведеното, проверете ги овие ставки по редослед:

  • Дали двете страни се на HTTPS? Атрибутот Secure значи дека колачето работи само на шифрирани врски. Ако вашата страница е на HTTP, прелистувачот нема да го прифати колачето. (Исклучок: развојна средина на localhost)
  • Дали адресата на Origin е точна? Адресата Access-Control-Allow-Origin мора точно да се совпаѓа со URL-то што го гледате во прелистувачот. Дури и разлика во www или завршна коса црта / ќе предизвика неуспех.
  • Дали OPTIONS барањето е успешно? Во табот Network на алатките за развивачи на прелистувачот, проверете го Preflight барањето (со OPTICS метод). Ова барање мора да се одговори со код 200 или 204 и точни CORS заглавја.
  • Дали колачето е складирано? Во прелистувачот, одете на DevTools ← Application ← Cookies и уверете се дека колачето е складирано со атрибутите Secure и SameSite=None.
  • Дали имате прокси или посреден заштитен ѕид? Понекогаш Cloudflare или веб-сервери како Nginx ги препишуваат заглавјата. Проверете ја и нивната конфигурација.

Резиме

Испраќањето колачиња во барања помеѓу домени бара координација на три фактори: серверот со Access-Control-Allow-Credentials: true и точен Origin, колачето со атрибути SameSite=None; Secure, и клиентот со активирање на credentials: 'include' или withCredentials: true. Следејќи ги овие три точки, проблемот ќе биде целосно решен.


Сигурна инфраструктура, мир за развивачите

Правилната имплементација на CORS и управувањето со колачиња е само дел од приказната; инфраструктурата на која работи вашиот проект, исто така, игра одлучувачка улога во стабилноста и безбедноста на услугата:

Radib Hosting — Брз веб-хостинг со целосна поддршка за бесплатен SSL и стандардна конфигурација на заглавја; идеален избор за хостирање на фронтендот и бекендот на вашите проекти.

Radib Virtual Server — Ако вашиот проект бара целосен пристап, посветени ресурси и слобода во конфигурацијата на веб-серверот (Nginx/Apache), Radib виртуелните сервери со моќен хардвер и стабилна мрежа се најдобриот избор за професионални API-ја.

Radib Debugging and Security Services — Ако се справувате со сложени CORS грешки, проблеми со автентификација или безбедносни предизвици, техничкиот тим на Radib, со длабоко искуство во решавање проблеми и обезбедување на веб-апликации, е тука да ви помогне да го решите проблемот од корен.

 

Дали Ви помогна овој одговор? 112 Корисниците го најдоа ова како корисно (112 Гласови)