Français

Percez les secrets de CORS (Cross-Origin Resource Sharing) et apprenez à activer en toute sécurité les requêtes inter-domaines dans vos applications web. Ce guide complet couvre les bases jusqu'aux configurations avancées, assurant une communication fluide et sécurisée entre les différentes origines.

Démystifier CORS : Un guide complet sur le partage des ressources entre origines multiples

Dans le web interconnecté d'aujourd'hui, les applications ont souvent besoin d'accéder à des ressources provenant de différentes origines. C'est là que le Partage des ressources entre origines multiples (CORS) entre en jeu. CORS est un mécanisme de sécurité crucial qui régit la manière dont les navigateurs web gèrent les requêtes d'une origine (domaine, protocole et port) vers une origine différente. Comprendre CORS est essentiel pour tout développeur web afin de construire des applications web sécurisées et fonctionnelles.

Qu'est-ce que la politique de même origine (Same-Origin Policy) ?

Avant de plonger dans CORS, il est important de comprendre la politique de même origine (Same-Origin Policy - SOP). La SOP est un mécanisme de sécurité fondamental implémenté dans les navigateurs web. Son but est d'empêcher les scripts malveillants d'un site web d'accéder à des données sensibles sur un autre site web. Une origine est définie par la combinaison du protocole (par ex., HTTP ou HTTPS), du domaine (par ex., example.com) et du numéro de port (par ex., 80 ou 443). Deux URL sont considérées comme ayant la même origine si elles partagent le même protocole, le même domaine et le même port.

Exemple :

La SOP empêche les scripts d'accéder à des ressources d'une origine différente, à moins que des mesures spécifiques, telles que CORS, ne soient en place pour l'autoriser.

Pourquoi CORS est-il nécessaire ?

Bien que la politique de même origine soit vitale pour la sécurité, elle peut aussi être restrictive. De nombreuses applications web modernes dépendent de la récupération de données depuis des serveurs différents, comme des API ou des réseaux de diffusion de contenu (CDN). CORS offre un moyen contrôlé d'assouplir la SOP et d'autoriser les requêtes légitimes entre origines multiples tout en maintenant la sécurité.

Imaginez un scénario où une application web hébergée sur http://example.com a besoin de récupérer des données d'un serveur d'API hébergé sur http://api.example.net. Sans CORS, le navigateur bloquerait cette requête à cause de la SOP. CORS permet au serveur d'API de spécifier explicitement quelles origines sont autorisées à accéder à ses ressources, permettant ainsi à l'application web de fonctionner correctement.

Comment fonctionne CORS : Les bases

CORS fonctionne grâce à une série d'en-têtes HTTP échangés entre le client (navigateur) et le serveur. Le serveur utilise ces en-têtes pour informer le navigateur s'il est autorisé à accéder à la ressource demandée. L'en-tête HTTP clé impliqué est Access-Control-Allow-Origin.

Scénario 1 : Requête simple

Une « requête simple » est une requête GET, HEAD ou POST qui remplit des critères spécifiques (par ex., l'en-tête Content-Type est l'un des suivants : application/x-www-form-urlencoded, multipart/form-data, ou text/plain). Dans ce cas, le navigateur envoie la requête directement au serveur, et le serveur répond avec l'en-tête Access-Control-Allow-Origin.

Requête du client (depuis http://example.com) :

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

Réponse du serveur (depuis http://api.example.net) :

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

{
  "data": "Quelques données du serveur"
}

Dans cet exemple, le serveur répond avec Access-Control-Allow-Origin: http://example.com, indiquant que les requêtes provenant de http://example.com sont autorisées. Si l'origine dans la requête ne correspond pas à la valeur de l'en-tête Access-Control-Allow-Origin (ou si l'en-tête est absent), le navigateur bloquera la réponse et empêchera le script côté client d'accéder aux données.

Scénario 2 : Requête preflight (pour les requêtes complexes)

Pour les requêtes plus complexes, telles que celles utilisant des méthodes HTTP comme PUT, DELETE, ou celles avec des en-têtes personnalisés, le navigateur effectue une requête « preflight » en utilisant la méthode HTTP OPTIONS. Cette requête preflight demande la permission au serveur avant d'envoyer la requête réelle. Le serveur répond avec des en-têtes qui spécifient quelles méthodes, quels en-têtes et quelles origines sont autorisés.

Requête preflight du client (depuis 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

Réponse du serveur (depuis 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

Explication des en-têtes :

Si la réponse preflight du serveur indique que la requête est autorisée, le navigateur procède à la requête réelle. Sinon, le navigateur bloque la requête.

Requête réelle du client (depuis 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": "Quelques données à mettre à jour"
}

Réponse du serveur (depuis http://api.example.net) :

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

{
  "status": "Données mises à jour avec succès"
}

En-têtes CORS courants

Voici une description des principaux en-têtes CORS que vous devez comprendre :

CORS dans différents langages côté serveur

La mise en œuvre de CORS implique généralement de configurer votre application côté serveur pour qu'elle envoie les en-têtes CORS appropriés. Voici des exemples de la manière de le faire dans divers langages et frameworks :

Node.js avec Express

Vous pouvez utiliser le package middleware cors :

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

const app = express();

// Activer CORS pour toutes les origines (À UTILISER AVEC PRUDENCE EN PRODUCTION)
app.use(cors());

// Alternativement, configurer CORS pour des origines spécifiques
// app.use(cors({
//   origin: 'http://example.com'
// }));

app.get('/data', (req, res) => {
  res.json({ message: 'Ceci est activé par CORS pour toutes les origines !' });
});

app.listen(3000, () => {
  console.log('Le serveur tourne sur le port 3000');
});

Python avec Flask

Vous pouvez utiliser l'extension Flask-CORS :

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

# Alternativement, configurer CORS pour des origines spécifiques
# CORS(app, resources={r"/api/*": {"origins": "http://example.com"}})

@app.route("/data")
def hello():
    return {"message": "Ceci est activé par CORS pour toutes les origines !"}

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

Java avec Spring Boot

Vous pouvez configurer CORS dans votre application Spring Boot en utilisant des annotations ou des classes de configuration :

Utilisation d'annotations :

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") // Autoriser les requêtes depuis http://example.com
public class DataController {

    @GetMapping("/data")
    public String getData() {
        return "Ceci est activé par CORS pour http://example.com !";
    }
}

Utilisation de la configuration :

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") // Autoriser les requêtes depuis http://example.com
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*");
    }
}

PHP

 "Ceci est activé par CORS pour http://example.com !");
echo json_encode($data);
?>

CORS et considérations de sécurité

Bien que CORS permette les requêtes inter-origines, il est crucial de le mettre en œuvre de manière sécurisée. Voici quelques considérations importantes :

Dépannage des problèmes CORS

Les problèmes CORS peuvent être frustrants à déboguer. Voici quelques problèmes courants et comment les résoudre :

Outils de débogage :

Scénarios CORS avancés

Bien que les concepts de base de CORS soient relativement simples, il existe des scénarios plus avancés à prendre en compte :

Bonnes pratiques CORS

Pour garantir une mise en œuvre sécurisée et efficace de CORS, suivez ces bonnes pratiques :

Conclusion

CORS est un mécanisme de sécurité essentiel qui permet des requêtes contrôlées entre origines multiples dans les applications web. Comprendre le fonctionnement de CORS et savoir comment le configurer correctement est essentiel pour tout développeur web. En suivant les directives et les bonnes pratiques décrites dans ce guide complet, vous pouvez construire des applications web sécurisées et fonctionnelles qui interagissent de manière transparente avec des ressources de différentes origines.

N'oubliez pas de toujours donner la priorité à la sécurité et d'éviter d'utiliser des configurations CORS trop permissives. En examinant attentivement les implications de sécurité de vos paramètres CORS, vous pouvez protéger vos applications et vos données contre les accès non autorisés.

Nous espérons que ce guide vous a aidé à démystifier CORS. Bon codage !