Appearance
Origines croisées
Principe
On parle souvent d'origine croisée lorsque l'on souhaite effectuer une requête.
Si un client effectue une requête vers un serveur, et que le nom de domaine du client est strictement identique au nom de domaine du serveur, le navigateur considère qu'il n'y a aucun risque de sécurité, puisqu'il s'agit bien du même serveur d'origine de la requête.
Néanmoins, si vous construisez une application Web qui est hébergée sur un nom de domaine différent d'un serveur, y compris si c'est sur un domaine similaire mais un sous-domaine différent, alors pour le navigateur il peut y avoir un risque de sécurité, notamment si une attaques par XSS survient, et va d'aborder chercher à savoir si le serveur cible autorise bien la requête du client
Attention
La protection offerte par le navigateur est certe une bonne chose pour se prémunir de nombreuses attaques, néanmoins elle n'est pas suffisante et vous ne devez pas vous reposer uniquement sur cela pour assurer la sécurité de votre application Web.
En-tête HTTP
Afin de pouvoir autoriser une requête, le navigateur va d'abord envoyer une première requête, qu'on appelle souvent dans le jargon un Pre-Flight, et qui va permettre au client de récupérer les informations sur cette requêtes via une requête HTTP avec la méthode OPTIONS.
Le serveur doit donc répondre aux requêtes OPTIONS envoyées par les clients avec les informations demandées par le navigateur.
Entre autre, l'information la plus importante est l'URL d'origine qui est autorisée par le serveur à faire des requêtes HTTP.
Si par exemple votre serveur est hébergée sur un sous-domaine server.domain.com et que votre client est hébergé sur le nom de domaine domain.com, alors le serveur doit envoyé un en-tête HTTP de réponse Access-Control-Allow-Origin avec en valeur l'origine autorisée, donc ici domain.com.
Si jamais le navigateur se rends compte qu'il y a une différence entre le nom de domaine à l'origine de la requête, et l'origine envoyée en réponse par le navigateur, alors il annule automatiquement la requête, donc le Pre-Flight aura échouée, et affichera l'erreur dans la console.
Si la requête OPTIONS réussie, alors il envoie la requête HTTP d'origine avec les bons paramètres demandés par le développeur.
On appelle souvent ce concept un CORS (Cross-Origin Resource Sharing).
CORS et Socket IO
Bien entendu, si vous utilisez le même nom de domaine entre le client et le serveur, vous pouvez ignorer totalement cette partie-là (mais n'ignorez pas les concepts pour autant qui sont utiles aussi dans d'autres contextes).
Par contre, si vous savez que le nom de domaine du serveur WebSocket et du client seront différentes, alors vous aurez besoin d'initialiser votre serveur avec les bonnes options.
Notamment l'options cors.origin de la classe Server.
typescript
import { Server } from "socket.io";
const io = new Server(9000, {
cors: {
origin: "domain.com"
}
});
Donc, si votre client est hébergé sur le nom de domaine client.domain.com, il faudra modifier cette origine dans l'initialisation de votre serveur WebSocket.
typescript
import { Server } from "socket.io";
const io = new Server(9000, {
cors: {
origin: "client.domain.com"
}
});