Une des utilisations de la programmation côté serveur est la saisie par l’utilisateur d’information dans un formulaire et la sauvegarde et le traitement de ces informations sur le serveur. Les formulaires sont toujours les balises form vues précédemment, mais deux nouvelles particularités apparaissent : des attributs action et method pour l’élément form indiquant respectivement la fonction à appeler quand le formulaire sera soumis et la méthode http à utiliser ; et un élément input de type submit (il s’agit d’un bouton dont l’appui va engendrer l’appel à l’action mentionnée au dessus).

<form action="traitement.py/foo" method="get">
<input type="text" name="champ"></input>
<input type="submit" value="Soumettre le formulaire" />
</form>

La fonction foo du fichier traitement.py manipulera les résultats et produira une page web. Elle prend un paramètre req et elle peut accéder aux valeurs stockées dans le formulaire via un dictionnaire nommé req.form.

def foo(req):
	page = "<html><body><p><strong>champ</strong> contient " + req.form["champ"] + ".</p></body></html>"
	return page

Exercices

Les scripts python nécessitant un serveur, nous utiliserons le serveur http de rtnfs (194.167.209.99). Chaque étudiant devra créer un dossier public_html dans son dossier personnel (pas celui de robert !), lui attribuer des droits permettant à tous (en particulier au serveur http) de lire les fichiers mais restreindre l’écriture et ne mettre ses fichiers que dans ce répertoire.

Pour avoir un shell sur le serveur, il faudra utiliser ssh (secure shell), et pour transmettre les fichiers, scp (secure copy, qui utilise le protocole ssh pour transférer des fichiers).

ssh altmeier@194.167.209.99

scp exercice1.py altmeier@194.167.209.99:public_html/

L’accès aux pages web générées se fera via des urls de la forme http://194.167.209.99/~altmeier/exercice1.py/foo.

Enquête

Nous souhaitons réaliser une enquête auprès des utilisateurs du site pour savoir s’ils sont pour ou contre les enquêtes.

  • Réaliser un formulaire web demandant à l’utilisateur ses nom, prénom et date de naissance, ainsi que son avis (pour ou contre).

    Pour la date de naissance, on pourra utiliser un input de type date qui permet de choisir dans un calendrier avec certains navigateurs.

  • Créer un fichier php qui récupère les valeurs entrées par l’utilisateur et les affiche de façon agréable (pour permettre à l’utilisateur de visualiser ses réponses avant de les valider).

    Pour écrire dans un fichier, il faut d’abord obtenir un descripteur de ce fichier avec la fonction open, écrire avec la procédure write et fermer le fichier avec close.

    # j'ouvre le fichier nommé resultats.txt en mode ajout (a) pour
    # écrire dedans et ne pas effacer ce qu'il contient (les autres modes
    # sont 'r' pour lire et 'w' pour écraser).
    # Attention aux droits nécessaires pour créer le fichier !!!
    fichier = open("resultats.txt", "a");
    
    # j'écris dans le fichier
    fichier.write("truc\n");
    
    # je relache le descripteur de fichier et ne pourrai plus écrire
    fichier.close();
  • Enfin réaliser la page affichant les statistiques. Elle doit lire le fichier créé précédemment, afficher le nombre de pour et de contre, ainsi que les pourcentages.

    On peut lire un fichier (préalablement ouvert) ligne par ligne avec une simple boucle for ligne in fichier. On utilisera le “slicing” pour obtenir des sous-chaînes

Exemple : http://194.167.209.99/~schwaller/formulaire.html

Mot de passe et traque des utilisateurs

Nous souhaitons maintenant que les utilisateurs de notre site puissent s’identifier pour accéder à du contenu personnalisés. Nous allons donc leur proposer de choisir un identifiant et un mot de passe.

Plusieurs questions se posent :

  • Comment allons-nous sauvegarder ces informations ?
  • Comment ne pas redemander ses identifiants à l’utilisateur à chaque retour sur le site ?
  1. Faire une version naïve de la page de création de compte qui demande login et mot de passe et sauvegarde cela tel quel dans un fichier.

    Est-il possible de mettre des droits sur le fichier interdisant aux autres élèves de le lire tout en permettant au site web de lire le fichier ?

    En pratique, on ne stocke pas les mots passe en clair mais on sauvegarde un hash1 du mot de passe salé2. En python, on peut utiliser la fonction crypt de la bibliothèque crypt.

    Avertissement : la sécurisation des mots de passe est un problème difficile. Les quelques lignes précédentes ne présentent que quelques uns des écueils que rencontre le développeur voulant réaliser cette opération lui-même. Un développeur web consciencieux doit utiliser des bibliothèques de gestion des mots de passe fiables et réputées et non une solution ad-hoc.

Exemple : http://194.167.209.99/~schwaller/mdp.py/index


  1. Une fonction de hash (ou fonction de hachage en français) transforme de façon injective son entrée en un représentant nommé hash. Et la fonction inverse (qui au représentant associe l’entrée initiale) est difficile. Pour vérifier un mot de passe, on calculera donc son hash et tentera de vérifier si c’est celui qui est sauvegardé. Mais si quelqu’un obtient la liste des hash, il ne pourra pas facilement en déduire les mots de passe de chaque utilisateur. Certaines vieilles fonctions de hashage ne doivent plus être utilisées car la fonction inverse n’est plus assez difficile, c’est par exemple le cas de md5.↩︎

  2. Un sel est un texte que l’on ajoute au mot de passe avant de calculer le hash. En effet, les fonctions de hash sont connues et les crackers disposent de rainbow tables associant les mots de passe classiques à leurs hash. Chaque site ayant un sel intelligemment choisi sera moins soumis au risque de découverte de nombreux mots de passe par rainbow tables. Ce n’est cependant pas suffisant pour assurer la sécurité une fois la base de données de mots de passe connue, car je connais alors le mot de passe de tous ceux ayant utilisé le même mot de passe que moi…↩︎