Un système de connexion discret est un système qui échappe au chemin de l'utilisateur. Cela rendra votre application plus agréable et plus soignée. Cet article vous guidera tout au long du processus de configuration des connexions d’utilisateur, puis ajaxifiera le processus en déplaçant le formulaire dans une boîte modale communiquant avec le serveur. De plus, cet article vous montrera comment créer la configuration à l'aide de jQuery et de Prototype afin que vous puissiez choisir votre bibliothèque préférée. Cet article suppose que vous avez de l'expérience avec Rails et jQuery ou Prototype..
Vous pouvez utiliser Adman65 / nettuts pour une connexion réussie. Assurez-vous d'utiliser de mauvaises informations d'identification afin de voir comment tout fonctionne..
Nous allons commencer par créer une application fictive comportant une page publique et privée. L'URL racine est la page publique. Il y a un lien de connexion sur la page publique. Si l'utilisateur se connecte avec succès, il est redirigé vers la page privée. Sinon, ils sont redirigés vers le formulaire de connexion. La page privée affiche le nom d'utilisateur. Nous l'utiliserons comme point de départ pour ajaxifier le site..
La première étape consiste à utiliser la commande rails pour générer une nouvelle application, puis installer et configurer authlogic..
$ cd dans un répertoire $ rails unobtrusive-login
Ajouter authlogic.
# /config/environment.rb config.gem 'authlogic'
Maintenant, installez les gemmes.
$ sudo gem installer gemcutter $ sudo gem tumble $ sudo rake gems: installer
Créez ensuite un modèle utilisateur et ajoutez les colonnes authlogic requises à la migration..
$ ./script/generate model L'utilisateur existe app / models / existe test / unit / existe test / fixtures / crée app / models / user.rb crée test / unit / test_utilisateur.rb crée test / fixtures / utilisateurs.yml crée db / migrate create db / migrate / 20100102082657_create_users.rb
Maintenant, ajoutez les colonnes à la nouvelle migration.
classe CreateUsers < ActiveRecord::Migration def self.up create_table :users do |t| t.string :login, :null => false t.string: crypted_password,: null => false t.string: password_salt,: null => false t.string: persistence_token,: null => false
Migrer la base de données.
$ rake db: migrate
Inclure authlogic dans le modèle utilisateur.
# /app/models/user.rb class User < ActiveRecord::Base acts_as_authentic end
Maintenant, nous pouvons créer un utilisateur. S'agissant d'une application de démonstration, la fonctionnalité Web pour la signature n'est pas requise. Alors ouvrez la console et créez un utilisateur:
$ ./script/console >> me = User.create (: login => 'Adman65',: password => 'nettuts',: password_confirmation => 'nettuts')
Nous avons maintenant un utilisateur dans le système, mais nous n'avons aucun moyen de vous connecter ou de vous déconnecter. Nous devons créer les modèles, les contrôleurs et les vues pour cela. Authlogic a sa propre classe pour le suivi des connexions. Nous pouvons utiliser le générateur pour cela:
# crée la session utilisateur $ ./script/generate UserSession
Ensuite, nous devons générer le contrôleur qui connectera / déconnectera les utilisateurs. Vous pouvez créer des sessions comme n'importe quelle autre ressource dans Rails.
# crée le contrôleur de session $ ./script/generate controller UserSessions
Définissez maintenant son contenu sur:
# /app/controllers/user_sessions_controller.rb class UserSessionsController < ApplicationController def new @user_session = UserSession.new end def create @user_session = UserSession.new(params[:user_session]) if @user_session.save flash[:notice] = "Login successful!" redirect_back_or_default user_path else render :action => : nouvelle fin fin fin
Cela ressemble exactement à un contrôleur généré via un échafaudage. Créez maintenant le contrôleur des utilisateurs qui a un contenu public et privé. Générer un contrôleur d'utilisateurs. À l'intérieur du contrôleur, nous utiliserons un filtre avant pour limiter l'accès aux zones privées. L'action index est publique et show est privé.
# crée le contrôleur d'utilisateurs $ ./script/generate controller users
Mettre à jour son contenu:
# /app/controllers/users_controller.rb class UsersController < ApplicationController before_filter :login_required, :only => : show def index end def show @user = utilisateur_de_connexion fin privé def login_required à moins que utilisateur_content flash [: error] = 'Vous devez être connecté pour voir cette page.' redirect_to new_user_session_path fin fin fin
Vous devriez remarquer que current_user est une méthode indéfinie à ce stade. Définissez ces méthodes dans ApplicationController. Ouvrez application_controller.rb et mettez à jour son contenu:
# contrôleur d'application classe ApplicationController < ActionController::Base helper :all # include all helpers, all the time protect_from_forgery # See ActionController::RequestForgeryProtection for details # From authlogic filter_parameter_logging :password, :password_confirmation helper_method :current_user_session, :current_user private def current_user_session @current_user_session ||= UserSession.find end def current_user @current_user ||= current_user_session && current_user_session.user end end
À ce stade, les modèles et les contrôleurs sont complets, mais pas les vues. Nous devons créer des vues pour un formulaire de connexion et le contenu public et privé. Nous utiliserons le joyau génial des générateurs pour créer une présentation de base.
$ sudo gem installer nifty-generators $ ./script/generate nifty_layout
Il est temps de créer le formulaire de connexion. Nous allons utiliser un partiel pour cela car à l'avenir, nous utiliserons le partiel pour afficher uniquement le formulaire de connexion dans la zone modale. Voici le code pour créer le formulaire de connexion. C'est exactement la même chose que si vous créiez un blog ou tout autre modèle..
# créer les vues de connexion # /app/views/user_sessions/_form.html.erb <% form_for(@user_session, :url => chemin_session_utilisateur) do | form | %> <%= form.error_messages %><%= form.label :login %> <%= form.text_field :login %>
<%= form.label :password %> <%= form.password_field :password %>
<%= form.submit 'Login' %> <% end %>
Rendez le partiel dans la nouvelle vue:
# /app/views/user_sessions/new.html.erb <% title 'Login Please' %> <%= render :partial => 'formulaire'%>
Créez des pages de base pour le contenu public et privé. L'action index montre le contenu public et show affiche le contenu privé.
# crée la page publique fictive # /app/views/users/index.html.erb <% title 'Unobtrusive Login' %>Contenu destiné au public
<%= link_to 'Login', new_user_session_path %>
Et pour la page privée:
# crée la page privée factice # /app/views/users/show.html.erb <% title 'Welcome' %>Bonjour <%=h @user.login %>
<%= link_to 'Logout', user_session_path, :method => : supprimer%>
Supprimez le fichier /public/index.html et démarrez le serveur. Vous pouvez maintenant vous connecter et vous déconnecter de l'application.
$ ./script/server
Voici quelques captures d'écran de l'application de démonstration. Le premier est la page publique.
Maintenant le formulaire de connexion
Et la page privée
Et enfin, accès refusé lorsque vous essayez de visiter http: // localhost: 3000 / user
Avant de continuer, nous devons comprendre comment le serveur et le navigateur vont travailler ensemble pour mener à bien ce processus. Nous savons que nous aurons besoin d'utiliser du JavaScript pour la boîte modale et le serveur pour valider les connexions. Soyons clairs sur la façon dont cela va fonctionner. L'utilisateur clique sur le lien de connexion, puis une boîte modale apparaît avec le formulaire de connexion. L'utilisateur remplit le formulaire et est soit redirigé vers la page privée, soit la boîte modale est actualisée avec un nouveau formulaire de connexion. La prochaine question est de savoir comment actualiser la zone modale ou dire au navigateur quoi faire après que l'utilisateur a soumis le formulaire. Rails a des blocs respond_to. Avec respond_to, vous pouvez indiquer au contrôleur de rendre un contenu différent si l'utilisateur a demandé XML, HTML, JavaScript, YAML, etc. Ainsi, lorsque l'utilisateur soumet le formulaire, le serveur peut renvoyer du JavaScript à exécuter dans le navigateur. Nous allons utiliser ceci pour rendre un nouveau formulaire ou une redirection. Avant de plonger plus profondément, passons en revue le processus dans l'ordre.
C'est le haut niveau. Voici la mise en œuvre de bas niveau.
Jetons un coup d'oeil à la nouvelle structure du contrôleur UserSessions.
classe UserSessionsController < ApplicationController layout :choose_layout def new @user_session = UserSession.new end def create @user_session = UserSession.new(params[:user_session]) if @user_session.save respond_to do |wants| wants.html redirect_to user_path(@user_session.user) wants.js render :action => : redirect # JavaScript pour faire la redirection end else respond_to do | veut | wanted.html render: new wanted.js # La valeur par défaut est create.js.erb end end def privée choix_layout (request.xhr?)? nil: 'application' end end
Comme vous pouvez le constater, la structure est différente. Dans if if, sinon conditionnel, respond_to est utilisé pour afficher le contenu correct. want.xx où xx est un type de contenu. Par défaut, Prototype et jQuery demandent texte / JavaScript. Cela correspond à wanted.js. Nous sommes sur le point de commencer la partie AJAX. Nous n'utiliserons aucun plugin sauf ceux pour les boites modales. Nous allons utiliser Facebox pour jQuery et ModalBox pour Prototype.
Rails a intégré le support pour Prototype. Les assistants JavaScript du Rail sont des fonctions Ruby qui génèrent du JavaScript qui utilise Prototype. Cette technique est connue sous le nom de RJS (Ruby JavaScript). Remote_form_for en est un exemple. Il fonctionne comme le standard for_for ajoute un JS lié à onsubmit qui soumet au formulaire à son action en utilisant sa méthode avec ses données. Je ne vais pas utiliser RJS dans cet article car je veux démontrer JS à la vanille. Je pense qu'en utilisant JS pur et en éliminant les assistants JS, l'article sera plus accessible aux développeurs moins expérimentés. Cela dit, vous pouvez facilement accomplir ces étapes en utilisant des assistants RJS / Prototype si vous choisissez.
L'ajout de Prototype à l'application est très simple. Lorsque vous utilisez la commande rails, les fichiers Prototype et Scriptaculous sont créés dans / public / JavaScripts. Les inclure est facile. Ouvrez /app/views/layouts/application.erb et ajoutez cette ligne dans la balise head:
<%= JavaScript_include_tag :defaults %>
JavaScript_include_tag crée des balises de script pour les fichiers par défaut de / public / JavaScripts, notamment prototype.js, effects.js et application.js. effects.js est scriptaculous. application.js est un fichier que vous pouvez utiliser pour conserver JS spécifique à l'application. Nous avons maintenant besoin d'un plugin de boîte modale. Nous allons utiliser ceci. C'est un très joli plugin de boîte modale inspiré par OSX. La source est hébergée sur GitHub, vous devrez donc cloner et déplacer les fichiers dans votre répertoire de projet. Par exemple:
$ cd code $ git clone git: //github.com/okonet/modalbox.git $ cd modalbox # déplace les fichiers dans les bons répertoires. # déplacez modalbox.css dans / public / stylesheets # déplacez modalbox.js dans / public / JavaScripts # déplacez spinner.gif dans / public / images
Maintenant, incluez les feuilles de style et JavaScript dans votre application.
<%= stylesheet_link_tag 'application' %> <%= stylesheet_link_tag 'modalbox' %> <%= JavaScript_include_tag :defaults %> <%= JavaScript_include_tag 'modalbox'%>
Maintenant, obtenons notre lien de connexion pour ouvrir une modalbox. Pour ce faire, nous devons ajouter du code JavaScript qui s'exécute lorsque le DOM est prêt et qui attache la modalbox à notre lien. Lorsque l'utilisateur clique sur le lien de connexion, le navigateur envoie GET à / user_sessions / new qui contient le formulaire de connexion. Le lien de connexion utilise le sélecteur # login-link. Mettez à jour le lien de connexion pour utiliser le nouvel identifiant dans /app/views/users/index.html.erb. Modifiez la fonction link_to comme ceci:
<%= link_to 'Login', new_user_session_path, :id => 'login-link'%>
Cela nous donne un # login-link. Maintenant, pour le JavaScript pour attacher une modalbox. Ajoutez ce JS dans /public/JavaScripts/application.js
document.observe ('dom: chargé', fonction () $ ('login-link'). observe ('clic', fonction (événement) event.stop (); Modalbox.show (this.href, titre : 'Login', width: 500););)
Il y a quelques JS simples pour quand l'utilisateur clique sur le lien, une boîte modale s'ouvre avec le href du lien. Reportez-vous à la documentation de modalbox si vous souhaitez davantage de personnalisation. Voici une capture d'écran:
Notez que l'intérieur de la boîte modale ressemble beaucoup à notre page standard. Rails utilise notre présentation d'application pour toutes les réponses HTML. Étant donné que nos fichiers XHR veulent des fragments HTML, il est judicieux de générer un rendu sans mise en page. Reportez-vous à l'exemple de contrôleur. J'ai introduit une méthode pour déterminer la mise en page. Ajoutez cela à UserSessionsController pour désactiver la mise en page pour XHR.
classe UserSessionsController < ApplicationController layout :choose_layout def new @user_session = UserSession.new end def create @user_session = UserSession.new(params[:user_session]) if @user_session.save flash[:notice] = "Login successful!" redirect_to user_path else render :action => : new end end def destroy current_user_session.destroy flash [: notice] = "Déconnexion réussie!" redirect_to root_path end private def choisir_layout (request.xhr?)? nil: 'application' end end
Actualisez la page et cliquez sur le lien pour obtenir quelque chose comme ceci:
Remplissez le formulaire et voyez ce qui se passe. Si vous remplissez le avec de mauvaises informations, vous êtes redirigé en dehors de la boîte modale. Si vous vous connectez correctement, vous êtes redirigé normalement. Selon les besoins, l'utilisateur doit pouvoir remplir le formulaire encore et encore dans la boîte modale jusqu'à ce qu'il se connecte correctement. Comment pouvons-nous accomplir cela? Comme décrit précédemment, nous devons utiliser AJAX pour soumettre des données au serveur, puis utiliser JavaScript pour mettre à jour la boîte modale avec le formulaire ou effectuer une redirection. Nous savons que la modalbox effectue un GET pour HTML. Après avoir affiché la modalbox initiale, nous devons écrire JS pour que le formulaire se soumette lui-même en style AJAX. Cela permet au formulaire de se soumettre à l’intérieur de la boîte modale. Ajouter simplement ce code après l'appel de la boîte modale ne fonctionnera pas car le XHR n'est peut-être pas terminé. Nous devons utiliser le rappel afterLoad de Modalbox. Voici le nouveau code:
document.observe ('dom: chargé', fonction () $ ('login-link'). observe ('clic', fonction (événement) event.stop (); Modalbox.show (this.href, titre : 'Login', largeur: 500, afterLoad: function () $ ('new_user_session'). Observe ('submit', function (événement) event.stop (); this.request ();)) ;);)
Form # request est une méthode pratique permettant de sérialiser et de soumettre le formulaire via Ajax.Request à l'URL de l'attribut d'action du formulaire, ce qui correspond exactement à ce que nous souhaitons. Vous pouvez maintenant remplir le formulaire à l'intérieur du modal sans le fermer. Le côté client est maintenant complet. Qu'en est-il du côté serveur? Le client soumet un POST qui demande à JS de revenir. Le serveur doit décider de renvoyer JavaScript pour mettre à jour le formulaire ou de rediriger une redirection. Dans UserSessionsController, nous utiliserons respond_to pour gérer la demande JS et un conditionnel pour renvoyer le JS correct. Commençons par gérer le cas de connexion ayant échoué. Le serveur doit renvoyer JS qui met à jour le formulaire et indique au nouveau formulaire de le soumettre via ajax. Nous placerons ce modèle dans /app/views/users_sessions/create.js.erb. Voici la structure de la nouvelle action de création:
def create @user_session = UserSession.new (params [: user_session]) if @ user_session.save flash [: notice] = "Connexion réussie!" redirect_to user_path else respond_to do | veut | wanted.html render: new wanted.js # create.js.erb end end end end
Maintenant remplissons create.js.erb:
$ ('MB_content'). Update ("<%= escape_JavaScript(render :partial => 'form')%> "); Modalbox.resizeToContent (); $ ('new_user_session'). observe ('submit', fonction (événement) event.stop (); this.request (););
Nous mettons d'abord à jour le contenu pour inclure le nouveau formulaire. Ensuite, nous redimensionnons la boîte modale. Ensuite, nous ajaxifions le formulaire comme avant. Voilla, vous pouvez remplir le formulaire autant de fois que vous le souhaitez.
Ensuite, nous devons gérer le cas de la redirection. Créez un nouveau fichier dans /app/views/users_sessions/redirect.js.erb:
window.location = "<%= user_path %>";
Maintenant, mettez à jour l'action create pour gérer le processus de redirection:
def create @user_session = UserSession.new (params [: user_session]) if @ user_session.save respond_to do | veut | wanted.html do flash [: notice] = "La connexion a réussi!" redirect_to user_path end wanted.js render: redirect end else respond_to do | veut | wanted.html render: new wanted.js # create.js.erb end end end end
Et c'est tout! Maintenant, essayez de vous connecter avec les informations d'identification correctes et vous serez redirigé vers la page privée. Pour un apprentissage plus approfondi, essayez d’ajouter une roulette et une notification indiquant à l’utilisateur que le formulaire est soumis ou qu’il est en cours de redirection. L'application fonctionne toujours si JavaScript est également désactivé..
Comme j'ai déjà couvert le processus Prototype, je ne vais pas entrer dans les mêmes détails qu'auparavant. Au lieu de cela, je vais passer rapidement à la description du code JavaScript alternatif à ajouter à l’application. La version jQuery aura exactement la même structure que la version Prototype. Tout ce que nous devons changer est ce qui se trouve dans application.js, create.js.erb et JavaScript / css inclut.
La première chose à faire est de télécharger jQuery et Facebox. Déplacez jQuery dans / public / JavaScripts en tant que jquery.js. Pour la face-avant, déplacez les images dans / public / images /, les feuilles de style dans / public / stylesheets et enfin le JS dans / public / JavaScripts. Maintenant, mettez à jour /app/views/layouts/application.html.erb pour refléter les modifications:
<%= h(yield(:title) || "Untitled") %> <%= stylesheet_link_tag 'facebox' %> <%= stylesheet_link_tag 'application' %> <%= JavaScript_include_tag 'jquery' %> <%= JavaScript_include_tag 'facebox' %> <%= JavaScript_include_tag 'application' %>
Facebox est livré avec une feuille de style par défaut qui suppose que vos images sont dans / facebox. Vous devrez mettre à jour ces sélecteurs dans facebox.css comme suit:
#facebox .b background: url (/images/b.png); #facebox .tl background: url (/images/tl.png); #facebox .tr background: url (/images/tr.png); #facebox .bl background: url (/images/bl.png); #facebox .br background: url (/images/br.png);
Maintenant, nous attachons facebox au lien de connexion. Ouvrez /public/JavaScripts/application.js et utilisez ceci:
$ (document) .ready (function () $ ('# login-lien'). facebox (loadingImage: '/images/loading.gif', closeImage: '/images/closelabel.gif',); )
Je remplace les paramètres par défaut pour les images afin de refléter le nouveau chemin de l'image. Démarrez le serveur et accédez à la page d'index. Vous devriez voir une belle facebox avec le formulaire de connexion:
Nous devons ensuite configurer le formulaire pour qu'il se soumette lui-même via AJAX. Comme avant, nous devrons utiliser des callbacks pour exécuter du code une fois la boîte modale prête. Nous allons utiliser la méthode post de jQuery pour la requête XHR. Facebox a un crochet après révéler que nous pouvons utiliser. application.js:
$ (document) .ready (function () $ ('# login-lien'). facebox (loadingImage: '/images/loading.gif', closeImage: '/images/closelabel.gif',); $ (document) .bind ('révéler.facebox', function () $ ('# new_user_session'). submit (function () $ .post (this.action, $ (this) .serialize (), null, " script "); return false;);););
Mettre à jour create.js.erb devrait être assez simple. Nous devons mettre à jour le contenu de la facebox et réajaxifier le formulaire. Voici le code:
$ ('# facebox .content'). html ("<%= escape_JavaScript(render :partial => 'form')%> "); $ ('# new_user_session'). submit (function () $ .post (this.action, $ (this) .serialize (), null," script "); return false; );
Et c'est tout! Voici le produit final:
Vous pouvez obtenir le code ici. Il existe des branches pour chaque bibliothèque afin que vous puissiez consulter les versions Prototype ou jQuery. Des questions, des commentaires, des préoccupations? Merci encore d'avoir lu!