Apache & PHP: La réécriture d'URL
Date de publication : 23/10/2003
Par
f-demu01
Introduction
1. Pourquoi réécrire ses liens ?
2. Généralités
3. La directive ErrorDocument
4. L'option FilesMatch
5. Le module mod_rewrite d'Apache
6. Conclusion
Introduction
L'utilisation de langages haut niveau, à l'instar de PHP, pour la
construction de sites Web, ainsi que l'interaction avec des bases de données
forcent aujourd'hui le webmaster à assaisonner tous ses liens d'une
multitude de paramètres de configuration, d'exécution, de mise en page, et
j'en passe. On est rapidement amené à produire des liens d'une longueur
astronomique et d'une complexité rare.
Le serveur Apache offre plusieurs moyens pour transformer ses liens et les
rendre plus lisibles, et augmenter la sécurité liée à l'apparition du nom
des paramètres dans l'URL.
Merci à
Armatatuxa,
Jérôme pour les re-lectures, ainsi qu'à
Henri Cesbron Lavau pour la précision concernant la génération de caches.
1. Pourquoi réécrire ses liens ?
Tout d'abord, par souci de clarté. Certains internautes (moi le premier)
n'apprécient guère les URL incompréhensibles et à rallonge dans la barre
d'adresses du navigateur. Une URL "formatée" sera beaucoup plus facile à
retenir que ce type de lien. Certes, il est possible de n'afficher que le
DNS quelle que soit la page demandée, mais cela diminue la pertinence des
robots des moteurs de recherche.
http://www.monsite.com/message/index.php?page=01&cat=10&langue=02
|
Il est également plus intéressant de produire des liens masqués en HTML
plutôt que des liens composés pour améliorer la qualité de votre
référencement. En effet, certains robots sont incapables d'interpréter les
liens composés. Si la proportion de ces robots s'amenuise avec le temps, il
en existe encore suffisamment pour qu'on les prenne en compte.
Enfin, la raison la plus flagrante de la mise en place d'un tel système est
la sécurité. Lorsque vous utilisez des liens composés, on voit apparaître
des valeurs, mais surtout des noms de variable, qui sont autant de portes
dérobées pour entrer dans votre site. Prenons un exemple extrême pour
l'illustrer: un script qui permettrait de visualiser le source d'un fichier
du serveur en passant celui-ci en paramètre
http://www.monsite.com/index.php?fichier=test.txt
pourrait être détourné afin de récupérer un fichier système
http://www.monsite.com/index.php?fichier=/etc/fstab
|
Bien sur, cet exemple est un cas extrême et simpliste que je vous invite à
ne jamais reproduire.
Quand bien même la liste n'est pas exhaustive, voilà plusieurs (bonnes)
raisons pour lesquelles il devient de plus en plus important d'utiliser ce
type de sécurité.
2. Généralités
Pour chaque méthode présentée, on utilisera l'exemple d'un site Web
contenant plusieurs rubriques, chaque d'elles contenant plusieurs pages,
toutes ces pages étant accessibles en plusieurs langues, en mode navigation
(normal) ou impression. Par souci de cohésion, la traduction des adresses se
fera en PHP, cela dit il est possible d'utiliser d'autres langages. Les
liens standards ont cette forme:
http://www.monsite.com/index.php?section=1&page=2&langue=fr&print=no
|
Lorsque vous utilisez l'URL rewriting, tous les liens que vous créerez sur
votre site devront suivre un patron commun. Voici le schéma du nom des pages
que nous voulons obtenir.
http://www.monsite.com/rubrique_page_langue_imprimer.html.
|
Le but de l'URL rewriting est donc d'intercepter côté serveur l'adresse de
la page demandée, d'en extraire les paramètres, et de renvoyer côté client
la page correspondante (qui n'a pas d'équivalent physique sur le serveur).
3. La directive ErrorDocument
Cette méthode, la plus simple, utilise la capacité d'Apache à rediriger vers
une même page tous les documents introuvables (plus connue sous le nom
d'erreur 404). Créez ou éditez le fichier .htaccess à la racine de votre
serveur, et ajoutez-y la ligne suivante:
Si votre site ne se situe pas à la racine du site Web, il faut mentionner
l'arborescence complète ( par exemple ./error.php ne fonctionnera pas).
On utilise ici le fichier error.php comme fichier de redirection afin de
séparer la partie de traitement de la partie affichage (gérée par
index.php), mais libre à vous de tout centraliser dans le fichier index.php.
Il ne reste plus qu'à remplir le fichier error.php pour le traitement des
paramètres.
$fic_tmp = explode( "/", $REQUEST_URI );
$fic_demande = array_pop($fic_tmp);
$parametres_tmp = explode( ".", $fic_demande );
$parametres = explode( "_", $parametres_tmp[0] );
$section = $parametres[0];
$page = $parametres[1];
$langue = $parametres[2];
$imprim = $parametres[3];
include_once("/var/www/index.php");
|
Notes :
Cette méthode m'a posé des problèmes pour l'utilisation des formulaires avec
la méthode POST: lors de l'envoi, la page se rechargeait sans raison
apparente.
Si cette méthode ne fonctionne pas et que vous êtes certains d'avoir suivi
toutes les étapes, poussez la taille de votre fichier de traitement (ici,
error.php) au delà de 512 octets, en y ajoutant des commentaires par
exemple: il s'agirait apparemment d'un bug lié à l'utilisation d'Internet
Explorer.
Attention lorsque vous utilisez cette méthode: le fait d'interpréter chaque
page comme étant un document inconnu augmente la taille de vos fichiers de
log access.log et error.log.
4. L'option FilesMatch
Afin d'interdire l'accès à certains documents au sein d'un répertoire sous
Apache, il est très fréquent de faire appel à la directive FilesMatch. Cette
directive permet également d'adopter un comportement selon le "type" de
fichier rencontré. Nous allons ici l'utiliser pour "diriger" les fichiers.
Cette méthode est un peu différente des deux autres, car elle ajoute
obligatoirement un niveau dans l'arborescence du site.
La première étape est de créer un fichier .htaccess à la racine du
répertoire pour lequel on veut activer cette fonctionnalité. On y ajoute
les lignes suivantes:
<FilesMatch "^(html)$">
ForceType application/x-httpd-php
<FilesMatch>
|
Cela peut se traduire ainsi: pour tout fichier dont le nom contient la
chaîne exacte "html", son type MIME est forcé à http-php. En pratique, tous
les fichiers contenus dans la sous-arborescence /html/ seront interprétés
comme étant du PHP. J'attire votre attention sur l'importance de ne
travailler qu'avec des liens absolus, l'utilisation de liens relatifs
(déconseillée de toutes façons ;) ) peut amener à des incohérences.
Considérons par exemple le script suivant
function affich_bouton() {
echo '<IMG SRC="./images/bouton.gif" alt="bouton" />';
}
|
On utilise la fonction affich_bouton dans le fichier index.php. Lorsque
l'on arrive sur le site, aucun problème, puisque l'URL est
http://www.monsite.com/ . A présent, cliquons sur un lien mettant en oeuvre
une URL réécrite. Celle-ci est de la forme www.monsite.com/html/01_fr.html,
et le script index.php utilise donc comme base www.monsite.com/html/ et
pour lui, le chemin de l'image devient donc
www.monsite.com/html/images/bouton.gif
Comme pour la première méthode utilisée, il faut à présent définir le
traitement des pages concernées par la règle sus-citée. A cet effet, il
faut créer au même niveau que .htaccess, un fichier nommé html, dont le
contenu sera le même que celui de "error.php" abordé au premier chapitre.
$fic_tmp = explode( "/", $REQUEST_URI );
$fic_demande = array_pop($fic_tmp);
$parametres_tmp = explode( ".", $fic_demande );
$parametres = explode( "_", $parametres_tmp[0] );
$section = $parametres[0];
$page = $parametres[1];
$langue = $parametres[2];
$imprim = $parametres[3];
include_once( "/var/www/index.php" );
|
5. Le module mod_rewrite d'Apache
Le module mod_rewrite est un module standard d'Apache qui permet de
manipuler les URL facilement: Brian Moore, auteur de la documentation Apache
à ce sujet, le décrit comme "le couteau suisse de la manupulation d'URL".
Tout d'abord, sachez que le module mod_rewrite d'Apache ne fonctionne pas
avec les versions inférieures à Apache 1.3.27, ce qui signifie entre autres
que les utilisateurs de EasyPHP 1.6, rencontreront des problèmes. Si votre
version d'Apache supporte l'URL Rewriting, la question se pose quant à sa
disponibilité chez votre hébergeur: en effet, beaucoup le désactivent pour
des raisons de sécurité.
Une connaissance de base des expressions régulières sera également un plus
non négligeable, je vous renvoie donc à cet effet au
tutoriel regex de Cyberzoïde.
La première chose à faire est l'activation, si vous travaillez en local, ou
si vous disposez d'un serveur dédié, du module mod rewrite: éditez votre
fichier httpd.conf, et ajoutez (ou, à défaut, décommentez) les deux lignes
suivantes:
LoadModule rewrite_module modules/mod_rewrite.so
AddModule mod_rewrite.c
|
Voila qui vous permet d'utiliser les règles de réécriture d'URL.
A présent, toujours en reprenant l'exemple de site de départ, nous allons
créer ou modifier le fichier .htaccess et définir la règle de réécriture.
Intéressons-nous aux quelques lignes que nous venons d'écrire dans ce
fichier: la première est une option à activer, pour des raisons de sécurité. Si l'option n'est pas active chez votre hébergeur, l'URL Rewriting peut ne pas fonctionner sur votre site.
La seconde ligne active le moteur de réécriture d'URL, lequel est désactivé
par défaut. Cette ligne est importante car elle vous permettra, si vous
utilisez plusieurs règles de réécriture, de toutes les ignorer en passant
le paramètre à Off, plutôt que de commenter toutes les règles une par une.
Cette commande s'utilise une seule fois dans le fichier .htaccess, quel que
soit le nombre de règles utilisées.
Enfin, la troisième ligne est la règle, qu'il faut décortiquer pour bien
comprendre. Celle ci comporte trois blocs: l'instruction RewriteRule, l'URL
à réécrire, et l'URL réécrite.
Si on s'intéresse au motif, on peut le décomposer comme suit: on trouve
quatre groupes entourés de parenthèses, séparés par des "_". Pour comprendre
en détails ces règles, utilisez un tutoriel sur les expressions régulières,
sinon, voici brièvement leur signification:
- groupe 1: ensemble de deux caractères compris entre 0 et 9 (section)
- groupe 2: idem groupe 1 (page)
- groupe 3: ensemble de deux lettres minuscules (langue)
- groupe 4: une lettre minuscule (imprim)
Voici donc nos quatre paramètres. Petite précision, le fait de les entourer
de parenthèse les sauvegarde dans des variables, dans leur ordre d'arrivée
($1, $2, ...$0 étant le nom de la page demandée).
Regardons à présent l'URL réécrite:
index.php?section=$1&page=$2&langue=$3&imprim=$4
|
Celle-ci est en tout point commune avec une URL standard, mais au lieu de
valeurs fixes pour les paramètres, on y trouve les variables créées juste
avant grâce aux parenthèses. Il ne vous reste plus qu'à récupérer dans
votre fichier index.php les valeurs des paramètres, et de les utiliser à
votre convenance.
A la fin de la ligne subsiste une directive: [L]. Il existe une liste
d'options qu'il est possible de combiner pour chaque règle. Celle que nous
utilisons ici permet de spécifier que cette règle sera la dernière
appliquée. Dans le cas présent, elle n'est pas nécessaire, mais elle le
devient lorsque l'on travaille avec plusieurs motifs.
Autre utilisation de la règle last, la création et la gestion de caches. Le
principe est de vérifier, pour chaque page demandée, si le fichier cache est
présent sur le serveur. Si c'est le cas, c'est cette page qui sera renvoyée
à l'internaute. Sinon, la page est créée.
Dans le cas ci-dessus, on teste l'existence de la page ( l'option -f permet
de s'assurer que la ressource est un fichier et non un répertoire). La
directive RewriteCond permet d'appliquer une réécriture seulement si la
condition spécifiée (ici, %{REQUEST_FILENAME}\.cache -f ) est
vérifiée. Etant donné que l'on spécifie [L] en fin de ligne, le moteur
n'ira même pas lire les lignes suivantes. En revanche, si la condition
n'est pas vérifiée, la ligne RewriteRule ([^.]+)\.html$ /$1.html.cache [L]
n'est pas prise en compte, ce qui permet l'exécution de la ligne suivante.
6. Conclusion
Chacune des méthodes proposées ici permet de faire correspondre à un fichier
n'ayant pas d'existence en tant que fichier physique sur un serveur Internet
un contenu HTML. Si l'URL rewriting permet de renforcer la sécurité de votre
site, cela n'est pas pour autant un gage d'inviolabilité, aussi pensez bien
aux autres aspects de la sécurité concernant votre site Internet.


Copyright © 2003 f-demu01. Aucune reproduction, même partielle, ne peut être faite
de ce site et de l'ensemble de son contenu : textes, documents, images, etc
sans l'autorisation expresse de l'auteur.
Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
Cette page est déposée à la
SACD.