Български

Разкрийте тайните на CORS (Споделяне на ресурси между различни източници) и научете как сигурно да активирате заявки между домейни във вашите уеб приложения. Това ръководство обхваща всичко от основите до напреднали конфигурации, осигурявайки безпроблемна и сигурна комуникация.

Демистифициране на CORS: Цялостно ръководство за споделяне на ресурси между различни източници

В днешния взаимосвързан уеб, приложенията често трябва да достъпват ресурси от различни източници. Тук се намесва Споделянето на ресурси между различни източници (CORS). CORS е ключов механизъм за сигурност, който управлява как уеб браузърите обработват заявки от един източник (домейн, протокол и порт) към друг. Разбирането на CORS е от съществено значение за всеки уеб разработчик, за да създава сигурни и функционални уеб приложения.

Какво е Политиката за същия източник?

Преди да се потопим в CORS, е важно да разберем Политиката за същия източник (SOP). SOP е основен механизъм за сигурност, внедрен в уеб браузърите. Целта му е да предотврати достъпа на злонамерени скриптове от един уебсайт до чувствителни данни на друг. Един източник се дефинира от комбинацията на протокол (напр. HTTP или HTTPS), домейн (напр. example.com) и номер на порт (напр. 80 или 443). Два URL адреса се считат за имащи същия източник, ако споделят един и същ протокол, домейн и порт.

Пример:

SOP ограничава достъпа на скриптове до ресурси от различен източник, освен ако не са въведени специфични мерки, като CORS, които да го позволят.

Защо е необходим CORS?

Въпреки че Политиката за същия източник е жизненоважна за сигурността, тя може да бъде и ограничаваща. Много съвременни уеб приложения разчитат на извличането на данни от различни сървъри, като например API или мрежи за доставка на съдържание (CDN). CORS предоставя контролиран начин за облекчаване на SOP и позволяване на легитимни заявки от различни източници, като същевременно поддържа сигурността.

Разгледайте сценарий, при който уеб приложение, хоствано на http://example.com, трябва да извлече данни от API сървър, хостван на http://api.example.net. Без CORS браузърът би блокирал тази заявка поради SOP. CORS позволява на API сървъра изрично да посочи кои източници имат право да достъпват неговите ресурси, което позволява на уеб приложението да функционира правилно.

Как работи CORS: Основите

CORS работи чрез поредица от HTTP хедъри, обменяни между клиента (браузъра) и сървъра. Сървърът използва тези хедъри, за да информира браузъра дали му е позволено да достъпи заявения ресурс. Ключовият HTTP хедър е Access-Control-Allow-Origin.

Сценарий 1: Проста заявка

"Проста заявка" е GET, HEAD или POST заявка, която отговаря на специфични критерии (напр. хедърът Content-Type е един от application/x-www-form-urlencoded, multipart/form-data или text/plain). В този случай браузърът изпраща заявката директно до сървъра, а сървърът отговаря с хедъра Access-Control-Allow-Origin.

Клиентска заявка (от http://example.com):

GET /data HTTP/1.1
Host: api.example.net
Origin: http://example.com

Сървърен отговор (от http://api.example.net):

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Content-Type: application/json

{
  "data": "Някакви данни от сървъра"
}

В този пример сървърът отговаря с Access-Control-Allow-Origin: http://example.com, което показва, че заявките от http://example.com са разрешени. Ако източникът в заявката не съответства на стойността в хедъра Access-Control-Allow-Origin (или ако хедърът липсва), браузърът ще блокира отговора и ще попречи на скрипта от страна на клиента да достъпи данните.

Сценарий 2: Предварителна заявка (за сложни заявки)

За по-сложни заявки, като тези, използващи HTTP методи като PUT, DELETE, или тези с персонализирани хедъри, браузърът извършва "предварителна" (preflight) заявка, използвайки HTTP метода OPTIONS. Тази предварителна заявка иска разрешение от сървъра, преди да изпрати действителната заявка. Сървърът отговаря с хедъри, които посочват кои методи, хедъри и източници са разрешени.

Клиентска предварителна заявка (от http://example.com):

OPTIONS /data HTTP/1.1
Host: api.example.net
Origin: http://example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header

Сървърен отговор (от http://api.example.net):

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: GET, PUT, DELETE
Access-Control-Allow-Headers: X-Custom-Header, Content-Type
Access-Control-Max-Age: 3600

Обяснение на хедърите:

Ако отговорът на предварителната заявка от сървъра показва, че заявката е разрешена, браузърът продължава с действителната заявка. В противен случай браузърът блокира заявката.

Действителна клиентска заявка (от http://example.com):

PUT /data HTTP/1.1
Host: api.example.net
Origin: http://example.com
X-Custom-Header: some-value
Content-Type: application/json

{
  "data": "Някакви данни, които трябва да бъдат актуализирани"
}

Сървърен отговор (от http://api.example.net):

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Content-Type: application/json

{
  "status": "Данните са актуализирани успешно"
}

Често срещани CORS хедъри

Ето разбивка на ключовите CORS хедъри, които трябва да разбирате:

CORS в различни сървърни езици

Внедряването на CORS обикновено включва конфигуриране на вашето сървърно приложение да изпраща съответните CORS хедъри. Ето примери как да направите това в различни езици и рамки:

Node.js с Express

Можете да използвате пакета за междинен софтуер cors:

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

const app = express();

// Активиране на CORS за всички източници (ИЗПОЛЗВАЙТЕ С ВНИМАНИЕ В ПРОДУКЦИОННА СРЕДА)
app.use(cors());

// Алтернативно, конфигурирайте CORS за конкретни източници
// app.use(cors({
//   origin: 'http://example.com'
// }));

app.get('/data', (req, res) => {
  res.json({ message: 'Това е с активиран CORS за всички източници!' });
});

app.listen(3000, () => {
  console.log('Сървърът работи на порт 3000');
});

Python с Flask

Можете да използвате разширението Flask-CORS:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

# Алтернативно, конфигурирайте CORS за конкретни източници
# CORS(app, resources={r"/api/*": {"origins": "http://example.com"}})

@app.route("/data")
def hello():
    return {"message": "Това е с активиран CORS за всички източници!"}

if __name__ == '__main__':
    app.run(debug=True)

Java със Spring Boot

Можете да конфигурирате CORS във вашето Spring Boot приложение, като използвате анотации или конфигурационни класове:

Използване на анотации:

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@CrossOrigin(origins = "http://example.com") // Разрешаване на заявки от http://example.com
public class DataController {

    @GetMapping("/data")
    public String getData() {
        return "Това е с активиран CORS за http://example.com!";
    }
}

Използване на конфигурация:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/data")
                .allowedOrigins("http://example.com") // Разрешаване на заявки от http://example.com
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*");
    }
}

PHP

 "Това е с активиран CORS за http://example.com!");
echo json_encode($data);
?>

CORS и съображения за сигурност

Въпреки че CORS позволява заявки от различни източници, е изключително важно да го внедрите сигурно. Ето някои важни съображения:

Отстраняване на проблеми с CORS

Проблемите с CORS могат да бъдат трудни за отстраняване. Ето някои често срещани проблеми и как да ги решите:

Инструменти за отстраняване на грешки:

Напреднали сценарии с CORS

Въпреки че основните концепции на CORS са сравнително ясни, има някои по-напреднали сценарии, които трябва да се вземат предвид:

Добри практики при CORS

За да осигурите сигурно и ефективно внедряване на CORS, следвайте тези добри практики:

Заключение

CORS е критичен механизъм за сигурност, който позволява контролирани заявки от различни източници в уеб приложенията. Разбирането как работи CORS и как да го конфигурирате правилно е от съществено значение за всеки уеб разработчик. Като следвате насоките и добрите практики, очертани в това цялостно ръководство, можете да създавате сигурни и функционални уеб приложения, които безпроблемно взаимодействат с ресурси от различни източници.

Не забравяйте винаги да давате приоритет на сигурността и да избягвате използването на прекалено разрешителни CORS конфигурации. Като внимателно обмисляте последиците за сигурността на вашите CORS настройки, можете да защитите вашите приложения и данни от неоторизиран достъп.

Надяваме се, че това ръководство ви е помогнало да демистифицирате CORS. Приятно кодиране!