Polski

Odkryj sekrety CORS (Cross-Origin Resource Sharing) i naucz się, jak bezpiecznie włączać żądania międzydomenowe w swoich aplikacjach webowych. Ten kompleksowy przewodnik omawia wszystko, od podstaw po zaawansowane konfiguracje, zapewniając płynną i bezpieczną komunikację między różnymi źródłami.

Demistyfikacja CORS: Kompleksowy przewodnik po Cross-Origin Resource Sharing

W dzisiejszej połączonej sieci, aplikacje często muszą uzyskiwać dostęp do zasobów z różnych źródeł. W tym miejscu do gry wchodzi Cross-Origin Resource Sharing (CORS). CORS to kluczowy mechanizm bezpieczeństwa, który reguluje, w jaki sposób przeglądarki internetowe obsługują żądania z jednego źródła (domena, protokół i port) do innego. Zrozumienie CORS jest niezbędne dla każdego programisty webowego, aby budować bezpieczne i funkcjonalne aplikacje internetowe.

Czym jest zasada tego samego pochodzenia (Same-Origin Policy)?

Zanim zagłębimy się w CORS, ważne jest, aby zrozumieć zasadę tego samego pochodzenia (Same-Origin Policy, SOP). SOP to fundamentalny mechanizm bezpieczeństwa wdrożony w przeglądarkach internetowych. Jego celem jest uniemożliwienie złośliwym skryptom z jednej witryny dostępu do wrażliwych danych na innej. Pochodzenie (origin) jest definiowane przez kombinację protokołu (np. HTTP lub HTTPS), domeny (np. example.com) i numeru portu (np. 80 lub 443). Uważa się, że dwa adresy URL mają to samo pochodzenie, jeśli mają ten sam protokół, domenę i port.

Przykład:

SOP ogranicza skryptom dostęp do zasobów z innego źródła, chyba że zostaną wdrożone określone środki, takie jak CORS, aby na to zezwolić.

Dlaczego CORS jest konieczny?

Chociaż zasada tego samego pochodzenia jest kluczowa dla bezpieczeństwa, może być również restrykcyjna. Wiele nowoczesnych aplikacji internetowych polega na pobieraniu danych z różnych serwerów, takich jak API czy sieci dostarczania treści (CDN). CORS zapewnia kontrolowany sposób na złagodzenie SOP i zezwolenie na uzasadnione żądania z różnych źródeł przy jednoczesnym zachowaniu bezpieczeństwa.

Rozważmy scenariusz, w którym aplikacja internetowa hostowana na http://example.com musi pobrać dane z serwera API hostowanego na http://api.example.net. Bez CORS przeglądarka zablokowałaby to żądanie z powodu SOP. CORS pozwala serwerowi API jawnie określić, które źródła mają pozwolenie na dostęp do jego zasobów, umożliwiając prawidłowe funkcjonowanie aplikacji internetowej.

Jak działa CORS: Podstawy

CORS działa poprzez serię nagłówków HTTP wymienianych między klientem (przeglądarką) a serwerem. Serwer używa tych nagłówków, aby poinformować przeglądarkę, czy ma ona pozwolenie na dostęp do żądanego zasobu. Kluczowym nagłówkiem HTTP jest Access-Control-Allow-Origin.

Scenariusz 1: Proste żądanie (Simple Request)

„Proste żądanie” to żądanie GET, HEAD lub POST, które spełnia określone kryteria (np. nagłówek Content-Type to jeden z application/x-www-form-urlencoded, multipart/form-data lub text/plain). W tym przypadku przeglądarka wysyła żądanie bezpośrednio do serwera, a serwer odpowiada z nagłówkiem Access-Control-Allow-Origin.

Żądanie klienta (z http://example.com):

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

Odpowiedź serwera (z http://api.example.net):

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

{
  "data": "Trochę danych z serwera"
}

W tym przykładzie serwer odpowiada z Access-Control-Allow-Origin: http://example.com, co wskazuje, że żądania z http://example.com są dozwolone. Jeśli pochodzenie w żądaniu nie pasuje do wartości w nagłówku Access-Control-Allow-Origin (lub jeśli nagłówek nie jest obecny), przeglądarka zablokuje odpowiedź i uniemożliwi skryptowi po stronie klienta dostęp do danych.

Scenariusz 2: Żądanie Preflight (dla żądań złożonych)

W przypadku bardziej złożonych żądań, takich jak te używające metod HTTP jak PUT, DELETE, lub te z niestandardowymi nagłówkami, przeglądarka wykonuje żądanie „preflight” przy użyciu metody HTTP OPTIONS. To żądanie preflight pyta serwer o pozwolenie przed wysłaniem właściwego żądania. Serwer odpowiada nagłówkami, które określają, jakie metody, nagłówki i źródła są dozwolone.

Żądanie Preflight klienta (z 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

Odpowiedź serwera (z 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

Wyjaśnienie nagłówków:

Jeśli odpowiedź preflight serwera wskazuje, że żądanie jest dozwolone, przeglądarka przechodzi do właściwego żądania. W przeciwnym razie przeglądarka blokuje żądanie.

Właściwe żądanie klienta (z 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": "Dane do zaktualizowania"
}

Odpowiedź serwera (z http://api.example.net):

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

{
  "status": "Dane zaktualizowane pomyślnie"
}

Typowe nagłówki CORS

Oto zestawienie kluczowych nagłówków CORS, które należy zrozumieć:

CORS w różnych językach po stronie serwera

Implementacja CORS zazwyczaj polega na skonfigurowaniu aplikacji po stronie serwera, aby wysyłała odpowiednie nagłówki CORS. Oto przykłady, jak to zrobić w różnych językach i frameworkach:

Node.js z Express

Możesz użyć pakietu middleware cors:

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

const app = express();

// Włącz CORS dla wszystkich źródeł (UŻYWAJ OSTROŻNIE W PRODUKCJI)
app.use(cors());

// Alternatywnie, skonfiguruj CORS dla określonych źródeł
// app.use(cors({
//   origin: 'http://example.com'
// }));

app.get('/data', (req, res) => {
  res.json({ message: 'CORS jest włączony dla wszystkich źródeł!' });
});

app.listen(3000, () => {
  console.log('Serwer działa na porcie 3000');
});

Python z Flask

Możesz użyć rozszerzenia Flask-CORS:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

# Alternatywnie, skonfiguruj CORS dla określonych źródeł
# CORS(app, resources={r"/api/*": {"origins": "http://example.com"}})

@app.route("/data")
def hello():
    return {"message": "CORS jest włączony dla wszystkich źródeł!"}

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

Java z Spring Boot

Możesz skonfigurować CORS w swojej aplikacji Spring Boot za pomocą adnotacji lub klas konfiguracyjnych:

Użycie adnotacji:

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") // Zezwól na żądania z http://example.com
public class DataController {

    @GetMapping("/data")
    public String getData() {
        return "CORS jest włączony dla http://example.com!";
    }
}

Użycie konfiguracji:

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") // Zezwól na żądania z http://example.com
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*");
    }
}

PHP

 "CORS jest włączony dla http://example.com!");
echo json_encode($data);
?>

CORS i kwestie bezpieczeństwa

Chociaż CORS umożliwia żądania z innych źródeł, kluczowe jest, aby wdrożyć go w bezpieczny sposób. Oto kilka ważnych kwestii:

Rozwiązywanie problemów z CORS

Problemy z CORS mogą być frustrujące w debugowaniu. Oto niektóre częste problemy i sposoby ich rozwiązania:

Narzędzia do debugowania:

Zaawansowane scenariusze CORS

Chociaż podstawowe koncepcje CORS są stosunkowo proste, istnieją bardziej zaawansowane scenariusze do rozważenia:

Dobre praktyki CORS

Aby zapewnić bezpieczną i wydajną implementację CORS, postępuj zgodnie z tymi dobrymi praktykami:

Podsumowanie

CORS to kluczowy mechanizm bezpieczeństwa, który umożliwia kontrolowane żądania z różnych źródeł w aplikacjach internetowych. Zrozumienie, jak działa CORS i jak go prawidłowo skonfigurować, jest niezbędne dla każdego programisty webowego. Postępując zgodnie z wytycznymi i dobrymi praktykami przedstawionymi w tym kompleksowym przewodniku, możesz budować bezpieczne i funkcjonalne aplikacje internetowe, które bezproblemowo współdziałają z zasobami z różnych źródeł.

Pamiętaj, aby zawsze priorytetowo traktować bezpieczeństwo i unikać zbyt permisywnych konfiguracji CORS. Starannie rozważając implikacje bezpieczeństwa swoich ustawień CORS, możesz chronić swoje aplikacje i dane przed nieautoryzowanym dostępem.

Mamy nadzieję, że ten przewodnik pomógł ci zdemistyfikować CORS. Miłego kodowania!