mercredi 8 juin 2011

Understanding Rack 2 : les middlewares

Bonjour,


Aujourd'hui, à mon réveil, j'ai senti une envie folle de coder. Donc après avoir pris ma douche, prié et pris mon petit déjeuner ( j'aurais pu vous inviter ! je sais ), je suis entré dans mon repertoire "Projets" et je suis tombé sur "Rack applications" et là je me suis rappelé que je vous dois la suite de la série "Understanding Rack" que j'ai commencée il y a quelques semaines déjà.


L'épisode 1 de cette série introduit Rack, son utilité et ses bases. Je vous conseiller de le lire avant de continuer avec cet article.


Dans cet épisode nous allons savoir ce qu'est un middleware Rack, à quoi il sert, comment en créer et surtout comment l'utiliser dans une application en production (ou en dév).


Rack middleware ?


un middleware rack est "juste" une application Rack qui a connaissance de l'existence d'autres applications Rack. J'explique ! Quand un middleware rack est invoqué, il peut passer la main à d'autres middlewares/applications pour des traitements spécifiques.


Exemple par le code :


module Rack
   class MonMiddleware
     def initialize(app)
       @app = app
     end
     def call(env)
       if @app
         status, headers, body = @app.call(env)
       else
         [ status, header, body ]
       end
     end
   end
end


Le code est assez simple et clair. Nous avons une application Rack qui "peut" passer la main à une autre application si cette dernière utilise ce middleware.


Donc, en résumé, un middleware Rack est une application utilisable par les applications Rack. Oui ! c'est tout ! ( pour le moment ).


Et pour donner un peu plus de "valeur" ou d'importance aux middlewares, nous allons parler de Rack::Restrictor.


un peu d'histoire !


Il y a quelques mois, pour le compte du SUP'Management Mauritanie,  j'ai dû écrire un petit middleware pour protéger certaines sections de leur SI.
Ils ont en place une application ( Rails ) appelée RubyCampus qui leur permet de gérer leurs étudiants, les enseignants, la paie, la gestion des examens et tout le tralala. Evidement ces modules ne sont pas tous développés par la communauté RubyCampus.


Le problème !


Après quelques mois d'utilisation ils se rendent compte qu'ils doivent restreindre l'accès à certaines parties de l'application à "leur équipe" d'informaticiens. Mais comment le faire ? Avoir deux  sous-applications : une pour les étudiants et une pour l'administration ? comment s'assurer que les étudiants ne pourront accéder qu'à "leur" application ?


la solution adoptée !


Pour régler ce problème, on a proposé que le staff devant accéder à la partie Admin soit dans un réseau et que seules les machines dans ce réseau pouvaient avoir accès à la section en question.


Mettre en place un tel réseau est chose aisée certainement ! Now la partie logicielle! 
La solution a été un middleware appelé Rack::Restrictor que vous pouvez télécharger ici. Il permet de spécifier la plage d'adresses ip acceptées et il se charge du reste.


Très simple comme solution mais ça marche.


voici le code :



Ok cool ! mais comment utilise-t-on un middleware Rack ?


Simple ! On va utiliser les fonctions du Rack::Builder !
( VOUS( certainement ) :hé ho c'est quoi Rack::Builder ? ... 
  Moi : on en reparlera plus tard )


Rack::Builder n'a que trois (3) méthodes : map, use et run.


Revenons à notre sujet. Créons une petite applicaton Rack et appelons notre middleware.



   class MonApp

     def call(env)
       status = 200
       headers= { "Content-Type" => "text/plain" }
       body   = "Bonjour tout le monde"
       return [ status, headers, body ]
     end

   end

Là nous avons une application très simple qui renvoie tout simplement une chaîne de caractéres. Mais notre application a besoin d'être sécurisée et réservée à très peu de personnes :)

pour ce faire nous allons utiliser Rack::Restrictor qui installable par " > gem install rack_restrictor ". 

   require 'rack_restrictor'


   use Rack::Restrictor, "192.168.0.1/24" 
   run MonApp.new


Ce que ça fait ! On require la gem, on appelle le middleware, on lui passe la plage que nous voulons autoriser et à la fin on lance notre application. 


PS : il faut toujours appeler votre application en dernier et prétez attention à l'ordre dans lequel vous appelez vos middlewares.


Lancer votre code et testez ! 


Je vais parler de Rack::Builder et comment embarquer des middlewares/applications Rack dans des applications web plus sérieuses écrites en utilisant Rails, Sinatra ou autre.


à plus

Aucun commentaire:

Enregistrer un commentaire