Découvrez comment télécharger une image avec Play! Framework en quelques minutes
Voici un exemple simple de la simplicité et de la puissance de Play! Framework, avec lequel je travaille pour l’eXpress-Board depuis quelques mois. La nouvelle version 1.1 est sortie mardi 2 novembre, avec de nouvelles fonctionnalités très intéressantes. La release note parle de Scala, de Glassfish, du nouveau modèle de base qui permet de faire du JPA ou de passer sur Google App Engine, du support de OAuth pour s’authentifier sur Twitter par exemple, de la fonction de création d’un WAR qui permet de déployer Play! sur un serveur d’application J2EE… bref beaucoup de nouveautés.
Voyons aujourd’hui comment simplement uploader une image vers le serveur.
1. Ajouter une action dans le controleur
Tout d’abord je vais déclarer une nouvelle action afin d’afficher un formulaire. Pour cela, dans un de mes contrôleurs, je déclare simplement une méthode static showUpload().
package controllers; import play.mvc.*; public class Application extends Controller { public static void index(){ render(); } public static void showUpload() { render(); } }
2. Ajouter une page html
Je créé ensuite une page html « showUpload.html » que je place dans le répertoire views/Application de mon application. Un simple formulaire pour télécharger l’image fera l’affaire :
<!DOCTYPE> <html> <head> <title>Upload</title> </head> <body> <h3>Télécharger une image</h3> #{form @upload(), method:'POST', enctype:'multipart/form-data'} <h4>Sélectionner le fichier</h4> <input type="file" name="fileTouilleur"/><br/> <br/> <input type="submit"/> #{/form} #{if flash.success} <div class="greenbox">${flash.success}</div> #{/if} #{if flash.error} <div class="errorbox">${flash.error}</div> #{/if} </body> </html>
Notez le DOCTYPE minimaliste : c’est du HTML 5 et cela fonctionne sur l’ensemble des navigateurs du marché. Les tags spéciaux que vous voyez sont des tags Groovy de Play! Framework. Limité en nombre, la souplesse de Groovy permet de faire des choses plus compliquées que l’Expression language utilisé dans JSF. Le tag form créé un formulaire, prépare aussi un champ HIDDEN unique pour éviter des problèmes de XSS par exemple. Le tag if permet de conditionner l’affichage d’une partie selon une expression. Le tag flash est un scope qui contient des variables temporaires, comme avec JBoss Seam ou Spring Webflow.
3. Implémenter l’action upload
Dans le formulaire de la page HTML, nous avons déclaré une action upload. Voici pour terminer comment récupérer le fichier téléchargé par l’utilisateur et le copier par exemple dans un répertoire de Play!
// Methode dans le meme controlleur public static void upload(File fileTouilleur){ notFoundIfNull(fileTouilleur); File newFile=Play.getFile("/public/shared/" + fileTouilleur.getName()); fileTouilleur.renameTo(newFile); fileTouilleur.delete(); flash.success("Success "+newFile.getAbsolutePath()); showUpload(); }
Oui vous ne rêvez pas, Play! Framework se charge pour vous de recevoir le fichier, de créer un fichier temporaire puis d’appeler simplement votre méthode upload. Le nom du paramètre est celui que j’ai mis dans mon formulaire HTML, à savoir fileTouilleur.
Conclusion
Il m’a fallut 5 minutes pour ajouter une fonction de téléchargement d’images pour les recruteurs du site de l’eXpress-Board. C’est aussi ce que j’apprécie avec Play! Framework : sa productivité et sa simplicité. Si je veux ensuite faire un composant de téléchargement compliqué, j’irai voir du côté de jQuery, ou d’un projet Javascript/Flash utilisé sur Drupal comme SWFUpload.
Rendez-vous le mercredi 10 novembre 2010 au yaJUG au Luxembourg où je co-présente Play! Framework avec Guillaume Bort, son fondateur.
Ce post était sur comment télécharger une image avec Play! Framework en quelques minutes mais ce que je retiens c’est surtout la gestion par défaut de XSS/CSRF.
Ce sont toutes les deux des failles assez évidente pour n’importe qui comprenant un tant soit peu le fonctionnement du web. Elles sont incluses dans OWASP Top 10 2007 et 2010 pour autant personne n’en parle vraiment ou semble s’en préoccuper. J’exagère sans doute un peu mais ce n’est pas la configuration par défaut de toutes les stacks. Alors effectivement de nombreuses stacks sont maison (vs framework full stack comme Play!) mais cela ne devrait pas être un très grand frein…
En ce qui concerne html escaping, je viens de faire un tour sur la documentation et cela est activé par défaut. De même, c’est un choix sensible mais loin d’être fait par tous…
J’ai juste une question : Il y a t il une strategie/raccourci pour les requetes GET authentifiée? Ou faut il faire a chaque fois un faux formulaire tel que celui présenté dans l’article?
sécurité avec Play!
Le plus gros reproche que je ferais à Play! c’est que tout est trop facile. This is unacceptable !
😉
Hier j’avais besoin de faire un traitement régulier en tâche de fond sur mes datas, je regarde la doc … ah! tu hérites de Job tu mets une petite annotation @Every(1h) tu écrits ton petit morceau de code pour faire ton traiment et pouf ça marche … 10 minutes montre en main ! Trop facile !
🙂
@Bertrand pas certain de comprendre ta question sur l’authentification. Pour gérer une session utilisateur, après une page d’authentification, Play! place dans un cookie crypté et signé ce que tu veux, comme un userId par exemple. C’est ce cookie qui passe de requete en requete et qui permet, dans ton controleur, de protéger tes pages. Est-ce que cela répond à la question ?
Attention, d’après la documentation officielle de Play ( http://www.playframework.org/documentation/1.1/security ) , pour avoir le champ hidden il faut le déclarer avec #{authenticityToken /} et le vérifier dans le controleur avec un checkAuthenticity(). Sinon, pas de protection contre le CSRF.
@Arnaud : merci pour ton retour, je n’avais pas encore vu ce point 🙂
@Nicolas
Effectivement, après relecture à froid, ma question n’était pas très compréhensible. Elle portait sur l’utilisation du ‘authenticityToken’ avec une methode GET et non sur l’authentification / la gestion de la session.
Une des failles connue (certes mineure) d’une protection CSRF est de passer le token dans l’url. (Après réflexion, je ne vois pas comment cela peut se justifier à part comme une mauvais utilisation de GET/POST mais cela est une autre histoire…) Je me demandais juste comme la gestion du token était réalisé avec GET puisque cela semblait être automatique dans les formulaires…
Mais Arnaud a, à priori, répondu indirectement : ce n’est pas automatique et cela se fait au cas par cas.