32-2 Configuration de CORS (Cross-origin Resource Sharing)

Le « Cross-origin resource sharing » (CORS) ou « partage des ressources entre origines multiples » est un mécanisme qui consiste à ajouter des en-têtes HTTP afin de permettre à un agent utilisateur d'accéder à des ressources d'un serveur situé sur une autre origine que le site courant. Un agent utilisateur réalise une requête HTTP multiorigine (cross-origin) lorsqu'il demande une ressource provenant d'un domaine, d'un protocole ou d'un port différent de ceux utilisés pour la page courante.
Une requête d'API est donc considérée comme Cross-origin lorsqu'elle demande une ressource provenant d'un domaine, protocole ou port différent.
Dans le cas qui nous occupe, le client (http://localhost:4200), appelle le serveur (http://localhost:3000) et bien qu'ils utilisent le même hôte (localhost), comme ils sont sur des ports différents (4200 et 300 respectivement), la requête est considérée comme Cross-origin (en provenance d'origines différentes).
L'exemple qui suit est un exemple extrême, mais permet de mettre en contexte pourquoi cette restriction existe.
Disons que vous avez un site web banque.ca qui offre des services bancaires. Un des services est une API qui permet à un utilisateur connecté de transférer de l'argent entre ses comptes. Cette API pourrait ressembler à ceci:
POST /api/transferMoney
{
"fromAccountId": "123456",
"toAccountId": "654321",
"amount": 1000
}
Avec une mauvaise configuration CORS:
Si banque.ca a une mauvaise configuration CORS, par exemple, en autorisant n'importe quel domaine à envoyer des requêtes:
Access-Control-Allow-Origin: *
Un attaquant pourrait créer un site web malveillant evil.ca qui, lorsqu'il est visité, effectue secrètement une requête vers banque.ca pour transférer de l'argent à l'insu de l'utilisateur. Le code malveillant pourrait ressembler à ceci:
<script>
fetch("https://bank.com/api/transferMoney", {
method: "POST",
body: JSON.stringify({
fromAccountId: "123456", // Supposons que c'est le compte de la victime
toAccountId: "999999", // Compte contrôlé par l'attaquant
amount: 1000
}),
credentials: "include" // Inclut les cookies de session de l'utilisateur
});
</script>
Lorsqu'un utilisateur connecté à banque.ca visite evil.ca, le script s'exécute, et à cause de la mauvaise configuration CORS de banque.ca, la requête est acceptée. L'argent est alors transféré du compte de la victime vers le compte de l'attaquant.
Solution:
Pour éviter cela, banque.ca peut mettre en place une politique CORS stricte qui n'autorise que les domaines de confiance à effectuer des requêtes. Par exemple:
Access-Control-Allow-Origin: https://banque.ca
Ceci garantirait que seules les requêtes provenant de banque.ca seraient acceptées.
Longue histoire courte, il faut autoriser le serveur à recevoir des requêtes d'une origine différente de la sienne (http://localhost:3000). Plus précisément, il doit accepter des requêtes de l'origine http://localhost:4200, soit le client.
Nous verrons plus loin comment configurer cette portion avec des variables d'environnement, mais pour l'instant, modifiez le fichier main.ts du serveur NestJS afin d'activer les CORS et permettre l'origine http://localhost:4200 d'effectuer des requêtes d'API.
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors({
origin: 'http://localhost:4200',
});
app.useGlobalPipes(new ValidationPipe());
const config = new DocumentBuilder()
.setTitle('Houdini API')
.setDescription("API de l'application Houdini")
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
Réessayez et ça devrait fonctionner! 🎉
