Introduction
La configuration du partage de ressources interdomaines (CORS) est essentielle pour garantir une communication fluide entre le frontend et l'API backend dans des applications modernes comme Contoso Chat. Cet article explore les techniques recommandées pour implémenter CORS dans le cadre du projet Contoso Chat, en mettant l'accent sur la sécurité et la flexibilité.
Importance de CORS dans Contoso Chat
Les mécanismes CORS permettent de contrôler les requêtes inter-domaines, ce qui est crucial pour une application de chat IA où le frontend et l'API fonctionnent souvent sur des domaines ou ports différents. Une configuration appropriée offre les avantages suivants :
- Accès sécurisé du frontend à l'API backend
- Protection contre les atatques cross-origin malveillantes
- Gestion flexible des politiques d'accès
- Adaptation aux environnements de développement et de production
Implémentation technique dans Contoso Chat
L'API backend de Contoso Chat est construite avec FastAPI et utilise le middleware CORSMiddleware pour gérer CORS. Le code principal se trouve dans le fichier src/api/main.py.
Configuration pour l'environnement de développement
En environnement de développement, la configuration est dynamique, prenant en charge des scénarios tels que GitHub Codespaces :
if espace_de_code:
domaine_8000 = f"https://{espace_de_code}-8000.app.github.dev"
domaine_5173 = f"https://{espace_de_code}-5173.app.github.dev"
point_final_ingestion = app_insights.split(';')[1].split('=')[1]
domaines_permis = [domaine_8000, domaine_5173, os.getenv("SERVICE_ACA_URI")]
else:
domaines_permis = [
o.strip()
for o in Path(Path(__file__).parent / "domaines_permis.txt").read_text().splitlines()
]
domaines_permis = ['*']
Ce code génère automatiquement une liste de domaines autorisés en fonction de l'environnement, permettant une transition fluide entre les configurations locales et cloud.
Configuration pour l'environnement de production
En production, les domaines autorisés sont gérés via un fichier dédié src/api/domaines_permis.txt, offrant un contrôle plus précis et une gestion des configurations externalisée.
Paramétrage du middleware CORS
Le middleware CORS est ajouté à l'application FastAPI avec les paramètres suivants :
app.add_middleware(
CORSMiddleware,
allow_origins=domaines_permis,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Cette configuration autorise les requêtes provenant des domaines spécifiés avec tous les types de méthodes et en-têtes HTTP, tout en supportant l'envoi d'informations d'authentification.
Meilleures pratiques recommandées
Éviter l'utilisation de l'astérisque en production
Pour renforcer la sécurité, il est conseillé de remplacer l'astérisque par une liste explicite de domaines en production :
domaines_permis = [
"https://chat.contoso.com",
"https://app.contoso.com",
]
Affiner le contrôle des méthodes et en-têtes
Plutôt que d'autorisre toutes les méthodes et en-têtes, limitez l'accès aux éléments strictement nécessaires :
app.add_middleware(
CORSMiddleware,
allow_origins=domaines_permis,
allow_credentials=True,
allow_methods=["GET", "POST", "OPTIONS"],
allow_headers=["Content-Type", "Authorization"],
)
Utiliser des variables d'environnement pour la configuration
Pour isoler les configurations par environnement, récupérez les domaines autorisés à partir de variables d'environnement :
domaines_permis = os.getenv("DOMAINES_AUTORISES", "").split(",")
Résolution des problèmes courants
Problème : En-tête Access-Control-Allow-Origin manquant
Solution : Vérifiez le fichier src/api/main.py pour vous assurer que le paramètre allow_origins du middleware CORSMiddleware est correctement défini.
Problème : Requêtes avec informations d'authentification refusées
Solution : Activez l'option allow_credentials=True dans la configuration CORS et évitez l'utilisation de l'astérisque pour allow_origins.
Problème : Échec des requêtes préliminaires OPTIONS
Solution : Assurez-vous que le serveur traite correctement les requêtes OPTIONS. Le middleware CORSMiddleware de FastAPI gère automatiquement ces requêtes lorsqu'il est correctement configuré.