Rediriger l'utilisateur en fonction d'un cookie avec Nginx
Récemment je me suis demandé comment je pourrais mettre en ligne plusieurs instances de la même application Web sur une seule adresse et en servir une différente en fonction de l’utilisateur visitant le site. Je voulais une solution aussi transparente que possible. J’ai donc choisi d’utiliser un paramètre d’URL et un cookie pour rediriger l’utilisateur vers l’instance voulue.
Le problème
Il y a de nombreuses raisons pour lesquelles vous pourriez vouloir faire cela. Vous pourriez avoir une instance pour chaque langue ou par thème, ou vous pourriez vouloir tester différentes versions d’une même fonctionnalité (A/B testing). Dans mon cas, j’avais besoin d’avoir une version différente de mon site Web personnel et de mon CV en fonction de l’entreprise à laquelle je postulais. Je voulais le faire sans avoir à créer un sous-domaine ou un chemin spécifique pour chaque instance.
La solution
Vous avez deux versions différentes de votre site Web, version A et version B.
Vous voulez montrer la version A par défaut et la version B lorsque
l’utilisateur se connecte à votre site via https://yoursite.com/?version=B
.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Version A</title>
</head>
<body>
<h1>Bienvenue sur la Version A</h1>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Version B</title>
</head>
<body>
<h1>Bienvenue sur la Version B</h1>
</body>
</html>
Les deux versions tournent sur la même machine mais sur des ports différents. Vous utilisez Nginx comme reverse proxy. Voici comment vous pouvez faire:
upstream versionA {
server 127.0.0.1:4000;
}
upstream versionB {
server 127.0.0.1:4001;
}
# Map pour choisir le backend en fonction de "backend_version"
map $backend_version $upstream {
A versionA;
B versionB;
default versionA;
}
server {
listen 80;
server_name yoursite.com;
location / {
# Version par défaut
set $backend_version A;
# Vérifie si le paramètre "version" est dans l'URL
if ($arg_version) {
set $backend_version $arg_version;
add_header Set-Cookie "version=$arg_version; Path=/";
# Redirige l'utilisateur vers la racine pour supprimer le paramètre
return 302 $uri;
}
# Vérifie si le cookie "version" est présent et met à jour la version
if ($http_cookie ~* "version=(\d)") {
set $backend_version $1;
}
# Si le cookie "version" n'est pas présent il est créé par défaut
if ($http_cookie !~* "version=(\d)") {
add_header Set-Cookie "version=$backend_version; Path=/";
}
# Redirige vers le backend approprié
proxy_pass http://$upstream;
}
}
Remplacez
yoursite.com
par votre nom de domaine et les ports4000
et4001
par les ports sur lesquels vos instances tournent.
Cette configuration doit être placée dans le répertoire
/etc/nginx/sites-available
et un lien symbolique doit être créé dans
/etc/nginx/sites-enabled
. Elle redirigera l’utilisateur vers l’instance
appropriée en fonction du paramètre d’URL version
. Si le paramètre n’est pas
présent, elle vérifiera si le cookie version
est défini. Si ce n’est pas le
cas, elle le définira sur la version par défaut. Le cookie sera défini à la
racine du site pour qu’il soit disponible sur toutes les pages.
Conclusion
Quand l’utilisateur visite https://yoursite.com/?version=B
, il sera redirigé
vers https://yoursite.com/
et naviguera sur la version B. Le cookie sera
défini et il continuera à voir la version B jusqu’à ce qu’il efface ses cookies.
Le routage est à la fois transparent et persistant.
Cette solution est simple et peut être facilement mise à jour pour inclure plus de versions différentes. C’est également un bon moyen de tester de nouvelles fonctionnalités de votre site Web sans affecter tous les utilisateurs. C’est une technique puissante à avoir à sa disposition.