Dans cette première vidéo d’une série d’astuces PHP, le présentateur explique comment protéger des images stockées dans un répertoire web tout en les rendant affichables dans les pages. Il commence par exposer le problème : les utilisateurs ne doivent pas pouvoir lister ou accéder directement aux fichiers image, même s’ils connaissent le nom du fichier. Il montre d’abord comment créer un fichier .htaccess dans le répertoire images et y placer la directive `Options -Indexes` pour désactiver l’indexation du dossier. Ensuite il ajoute `Deny from all` afin d’interdire tout accès direct au répertoire. Après avoir constaté que les balises `<img>` ne peuvent plus charger les images, il introduit une solution intermédiaire : un script PHP (image.php) qui lit le fichier image avec `filegetcontents`, envoie le bon en‑tête MIME (`Content‑Type: image/jpeg`) et renvoie le contenu. La balise `<img>` pointe alors vers ce script, qui agit comme un proxy autorisé par le serveur. Le présentateur montre le résultat fonctionnel, explique que le serveur peut toujours lire le fichier même si le client est bloqué, et mentionne que la même technique s’applique à d’autres types de fichiers (PDF, etc.) en adaptant les en‑têtes. Il conclut en rappelant que stocker les images dans une base de données est une alternative, mais que la méthode .htaccess + PHP est simple et efficace pour sécuriser l’accès.
Chapters
Bonjour à tous et bienvenue dans cette première vidéo d'une série qui s'intéresse aux astuces du développement web principalement à l'aide du langage PHP. Nous allons voir ensemble des techniques que je n'ai pas traitées dans les séries consacrées au cours et on commence par une question qui m'a souvent été posée au sujet de la sécurisation des images dans un serveur web tout en ayant la possibilité de les afficher sur la page. En effet, si vous avez créé un site où les utilisateurs peuvent déposer leurs images, mais qu'ils ne souhaitent pas divulguer à tout le monde, comme les imprimer lors d'une discussion, alors la première idée qui vient à la tête, c'est de ne pas placer ces images-là dans un dossier, mais on va plutôt les enregistrer dans une base de données. Dans ce cas, c'est à vous de décider quand et à qui les afficher selon les critères que vous aurez pris en compte dans votre programme. Cependant, placer les images dans une base de données n'est pas toujours la meilleure idée. Et on aura probablement l'occasion de parler de ça après. Alors on va effectivement déposer nos images normalement dans un dossier, mais on va leur restreindre l'accès. Le code que nous avons devant nous permet d'afficher une image sur le navigateur. L'image en question s'appelle image1.jpg et elle est placée dans un dossier qui s'appelle images. Et le dossier en question est censé contenir les images du projet. Comme c'est le cas ici, je dispose de 2 images: image1.jpg et image2.jpg. Alors jusqu'ici rien de spécial, mais imaginez que l'utilisateur a saisi l'adresse suivante: En fait, on a listé tous les fichiers et dossiers qui sont inclus dans le dossier images. Dans mon cas j'en ai que 2 qui sont image1.jpg et image2.jpg. Bien que ça peut vous paraître normal, c'est déconseillé de permettre aux utilisateurs de lister le contenu des dossiers, en l'occurrence si celui-ci contient des informations qui sont confidentielles. Alors imaginez que les images qui s'appellent image1.jpg et image2.jpg sont vraiment confidentielles et on veut les afficher selon des conditions que l'on a traitées dans notre code comme après authentification par exemple. La solution la plus simple, c'est d'interdire radicalement aux utilisateurs de lister les informations des dossiers. Pour faire ceci, on fera appel à un fichier qui s'appelle .htaccess. Ce nom ne vous est probablement pas étranger. En fait, il s'agit d'un fichier de configuration du serveur web Apache. Que ce dernier dispose d'un fichier de configuration qui lui est propre, mais le fichier .htaccess est une extension de la configuration que le développeur a la liberté de placer là où il souhaite dans son projet. Alors dans notre cas, on va créer le fichier .htaccess et on va le mettre dans le dossier qui s'appelle images comme ceci. Pour manipuler ce fichier, je préfère utiliser la ligne de commande puisque c'est un fichier caché, sinon vous pouvez toujours le manipuler à l'aide d'un éditeur normal comme Sublime Text par exemple. Donc je vais me rendre dans le dossier. Ensuite je mets le dossier images. Quand je liste, ça contient bien les 2 images que je vous ai montrées qui sont image1.jpg et image2.jpg. Maintenant je vais créer un fichier qui s'appelle .htaccess. Bien sûr il est préfixé par un point pour désigner que c'est un fichier caché. Dans ce fichier, je vais ajouter une directive qui interdit de lister le contenu du dossier. C'est la commande options avec la valeur -6 ou bien -indexes. Maintenant j'enregistre. Alors je vais à nouveau essayer de lister et là ça me donne bien que c'est interdit. Alors jusqu'ici c'est bien, je veux pas lister le contenu de mon dossier qui s'appelle images. Bien, Bien sûr, le fichier .htaccess, il a l'effet uniquement sur ce dossier-là et sur les sous-dossiers qui sont probablement inclus dans le dossier images. Cependant, un utilisateur peut toujours accéder à une image s'il connaît son nom. Par exemple, en regardant le code HTML, je sais que l'image s'appelle image1.jpg. Alors il suffit de la mettre ici et voilà, mon image est affichée. Même chose pour image2. Alors on constate bien que l'utilisateur, une fois qu'il dispose du chemin complet de l'image, alors il peut l'afficher à sa guise. Ce qu'on va faire maintenant, c'est interdire carrément au client d'accéder à ce dossier, c'est-à-dire qu'il peut pas afficher carrément ce qu'il y a dedans. Alors on va ajouter notre directive à notre fichier .htaccess. On mettra tout simplement DenyFromAll. Deny from all signifie que l'utilisateur ne peut pas accéder à ce dossier. Bien entendu, la directive deny peut être personnalisable. Ça veut dire je peux spécifier la manière avec laquelle je vais interdire l'accès, soit par adresse IP, par nom de domaine, ou bien par des variables d'environnement spéciales, etc. Maintenant, j'ai mis all pour dire que c'est strict, on peut pas accéder à ce dossier-là dans tous les cas. Alors j'enregistre. Essayons de rafraîchir la page. Alors on constate bien qu'on n'a pas d'accès à l'image directement non plus. Alors jusqu'ici on considère bien que nos images sont bien sécurisées alors que personne ne peut les scruter directement. Et pourtant il y a un problème qui subsiste. Si on regarde le code HTML de plus près, on verra bien que le navigateur a besoin d'accéder à l'image directement pour l'afficher parce que la balise img, puisque ça fait partie du HTML, est exécutée sur le client. Donc c'est le navigateur qui va l'exécuter et à ce moment-là il pourra pas afficher l'image. Regardons ce qui va se passer maintenant si j'exécute la page index.php sur le navigateur. Voilà, l'image n'est plus affichée. Bien que le chemin est correct, mais l'image n'est plus accessible. Alors ce qu'on va faire maintenant, c'est créer une autre page PHP qui va se charger d'importer l'image depuis le serveur et la présenter à la page index.php. Donc la page on va l'appeler image.php. Cette page va importer l'image concernée à l'aide de la fonction file_get_contents et dedans on mettra le chemin vers l'image voulue. Par exemple image/image1.jpg. Et on mettra echo, c'est-à-dire que je vais afficher cette image une fois importée du serveur. Et maintenant il suffit de spécifier le chemin vers la page image.php en guise de src de la balise img comme ceci. Exécutons maintenant pour voir le résultat. Alors l'image est bien affichée. Donc vous avez vu que je n'ai plus d'accès au dossier images et non plus aux images une à une. Et pourtant le navigateur peut toujours afficher l'image en passant par l'intermédiaire d'une page qui s'appelle image.php qui va s'assurer d'importer l'image depuis le serveur. Parce que figurez-vous bien que quand j'ai mis la directive deny from all, Dans ce cas, seul le client ne peut pas accéder à ce dossier, mais le serveur si. Et dans ce cas, cette instruction est exécutée par le serveur. Il y a juste un truc que l'on peut ajouter pour éviter les problèmes, c'est qu'on va spécifier les en-têtes de cette manière. Faut bien spécifier que le résultat de retour attendu c'est bien une image de type JPEG. On a déjà vu ces notions avant, on appelle ça le type et le MIME. Réexécutons. Comme je l'ai dit avant, il s'agit d'une méthode simple qui permet de sécuriser l'accès aux images de telle sorte à interdire aux utilisateurs de lister le contenu des dossiers ou bien accéder directement aux images sans passer par votre code. Mais il reste quand même à bien écrire celui-ci, ça veut dire votre code, afin que le résultat soit plus optimisé. L'exemple que j'ai fait là traite uniquement des images, en l'occurrence de type JPEG. Cependant, on peut appliquer le même principe sur les documents PDF ou bien d'autres types de fichiers. Il suffit de changer les en-têtes et ça devrait marcher. Merci pour votre attention et à la vidéo prochaine.