PHP, MySQL et .htaccess

neopium

Membre actif
9 Juin 2004
121
1
45
Bonjour tout le monde,

Je suis en train de créer un site web en php/MySQL pour une association dont je fais partie. Dans ce site web, il y a une zone "privée", réservée aux adhérents. Les login/mot de passe des adhérents sont stockés dans ma base de donnée MySQL et j'ai mis en place le système d'authentification (il y a un mois de ça, je ne connaissais rien au php et à MySQL... et comme j'ai tout appris sur le tas, ça n'a pas été simple...). Afin de préserver les informations des adhérents et de l'asso, je dois avoir un système sécurisé.
L'accès à la zone "privée" se fait par https. Toute page de l'intranet verifie que vous etes bien connecte avant de afficher le contenu ou vous renvoie sur la page de connexion.
J'ai aussi crée un fichier .htaccess afin d'empecher l'indexation des repertoires. Donc je croyais que mon site etait securise... mais si un utilisateur tape dans son navigateur http://www.monsite.com/prive/monjournal.pdf, le document s'affiche dans le navigateur sans que l'utilisateur n'ai eu à s'identifier.
J'ai donc pensé qu'il fallait que je crée un fichier .htaccess plus restrictif, avec son fichier .htpasswd associé... mais voila, pour faire ce dernier, il faut crypter les mots de passe a chaque fois qu'un utilisateur est rajoute ou modifie son mot de passe. Il faut aussi effacer l'utilisateur qui est supprime de la base de donnee...
Bref, il faut faire une sorte de synchronisation de la bdd mysql avec le fichier .htpasswd... y a-t-il moyen de faire ça facilement ? Y a-t-il des fonctions automatiques existantes ? Ou est-ce carrément la mauvaise méthode ? Comment procéder alors ?
Pour pimenter le tout, je n'ai pas accès aux fichiers de configuration d'Apache...
Merci pour votre aide
@+
Neo
 
Synnchroniser un .htpasswd et ta base, c'est faisable.
C'est peut être un peu lourd, mais ça a ses avantages.


Par contre tu peux aussi protéger tes fichiers avec un script: tu mets tes fichiers dans un répertoire en accès totalement interdit, et tu crées un script (download.php par exemple) qui, si l'utilisateur est identifié, renverra le fichier (avec la fonction fpassthru par exemple) dont le nom lui est donné (via l'URL).

Pour utiliser fpassthru il faut penser aux fioritures, en particulier le header "Content-Type". Attention, ce script doit également être sécurisé et ne pas donner accès à n'importe quel fichier sur ton site, pense à toujours vérifier que le fichier qui va être renvoyé est dans le répertoire dont tu autorises l'envoi des fichiers (je me comprends).

Mais le htpasswd c'est bien aussi !
 
J'ai eu l'occasion d'essayer les 2 méthodes.

Dans la première, on gère un .htpasswd de façon dynamique.
Dans la seconde, on verrouille complètement le dossier, et on demande à php de faire un accès direct au fichier.

La seconde méthode est largement plus facile et plus élégante.
En effet, tes liens pointent vers un fichier nommé downdload.php qui s'occupe de renvoyer un header pour que ton navigateur fasse un download, et ensuite, tu peux faire un readFile vers la sortie standard. Le fichier est téléchargé.

J'ai fait un site ou l'utilisateur choisi dans une liste d'images celles qu'il souhaite. Il peut même rajouter un cropping ou un scaling sur l'image. Toutes ces images sont croppée et mise à l'échelle avec la libairie gd, en mémoire vive sur le serveur. Puis elles sont toutes combinées dans un zip.

Tout est fait en mémoire vive et il n'y a aucune génération de fichier intermédiaire. Bien sur, ce système est à déconseiller pour des images lourdes avec beaucoup d'accès conccurrents.

Tout ça pour dire que cette technique marche très bien.
 
Merci à tous les deux pour ces conseils. J'ai effectivement mis en place le système avec fpassthru et ça marche nickel, c'est génial. Gérer le fichier .htacces de manière dynamique était mon idée de base, mais ça m'aurait demandé beaucoup trop de temps... aaah, les plaisirs du bénévolat... en tout cas, merci beaucoup !
 
Après reflexion et test, j'ai qd même un problème... voici le code que j'ai mis en place :
Bloc de code:
 // Verifie que l'utilisateur est bien connecte
 include ("./login_check.php");
 
 // Recuperation de l'URL et du format du document
 $url=$_GET['URL'];
 $format=$GET['TYPE'];
 
 switch ($format)
 {
   case pdf : $ContentType="application/pdf";
   case doc : $ContentType="application/msword";
   default: $ContentType="unknown format";
 }
 
 // Ouverture du document
 $fp = fopen($url,'rb');
 header("Content-Type: $ContentType");
 header("Content-Length: ".filesize($url));
 fpassthru($fp);
 exit;
Ca marche très bien sur Windows et Linux... mais sur Mac (Safari ou Firefox), il me télécharge bien le fichier pdf mais l'enregistre sous le nom download.php (le nom du programme).. et du coup essaye de l'ouvrir avec Dreamweaver... et forcément, ça ne marche pas des masses...
Une solution ?
 
Petit problème là :
$format=$GET['TYPE'];

Non ?
C'est $_GET ...
 
bien vu, effectivement, erreur bête de fin de journée... mais ce ne change rien... il y a aussi un bug dans mon switch case, mais ça ne vient pas de là, car si je remplace en hard par le bon content-type, il me telecharge qd meme le fichier sous le nom .php
 
Une solution (c'était la mienne quand j'utilisais un tel script) c'est d'appeler le script par, par exemple:
htpp://www.monsite.truc/download.php/lefichier.jpg?mesautresvariables=leursvaleurs
Comme ça le navigateur il lui met comme nom "lefichier.jpg". (Je te laisse trouver comment récupérer le nom du fichier en question).

Attention, si ça affiche une page quand l'utilisateur n'est pas identifié, ou redirige sur une autre page, il faut tenir compte du fait que le navigateur croit être dans le répertoire "download.php" et donc biaiser les liens relatifs.

Il est possible que ça ne marche pas selon les réglages du serveur. (Enfin je sais pas).

Il y a peut être une autre méthode plus "propre" (le header "content-location" peut-il servir ? :mouais: )
 
Sur la page de documentation PHP de la fonction header, ils donnent ceci comme exemple :

Bloc de code:
<?php
// We'll be outputting a PDF
header('Content-type: application/pdf');

// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');

// The PDF source is in original.pdf
readfile('original.pdf');
?>

En espérant que ça puisse t'aider.
 
  • J’aime
Réactions: Spyro
molgow a dit:
Sur la page de documentation PHP de la fonction header, ils donnent ceci comme exemple :

Bloc de code:
<?php
// We'll be outputting a PDF
header('Content-type: application/pdf');

// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');

// The PDF source is in original.pdf
readfile('original.pdf');
?>

En espérant que ça puisse t'aider.
merci pour cette formule "magique" !
C'est effectivement la ligne "header('Content-Disposition: attachment; filename="downloaded.pdf"');" qui manquait... maintenant, tout marche comme sur des roulettes
@+
Neo
 
Re-bonjour,

Juste pour info, mon switch case n'était pas bon car j'avais oublié les "break;"... un jour, j'oublierai ma tête ;-)...
Autre information, plus intéressante pour vous et dégotée sur le forum de MacBidouille, une solution pour gérer le .htaccess dynamiquement : il s'agit d'un module apache appelé mod_auth_mysql qui permet à apache de controler l'accès au site web directement à partir de la base de données. J'ai contacté mon hébergeur pour savoir s'il était installé sur mon serveur mutualisé... Si ça marche, ça risque d'être plus élégant, et moins risqué au niveau sécurité (le path du fichier étant passé par l'url, rien n'empêche un utilisateur de modifier l'url et de récupérer d'autres fichiers...)
@+
Neo