So erstellen Sie ein unauffälliges Anmeldesystem in Rails

Ein unauffälliges Anmeldesystem verhindert den Benutzer. Ihre Anwendung wird dadurch schöner und polierter. In diesem Artikel werden Sie durch die Einrichtung von Benutzeranmeldungen geführt. Anschließend wird der Vorgang beschleunigt, indem Sie das Formular in eine modale Box verschieben, die mit dem Server kommuniziert. Außerdem wird in diesem Artikel beschrieben, wie Sie das Setup mit jQuery und Prototype erstellen, sodass Sie Ihre Lieblingsbibliothek auswählen können. Dieser Artikel setzt voraus, dass Sie Erfahrung mit Rails und jQuery oder Prototype haben.


Sie können Adman65 / nettuts für ein erfolgreiches Login verwenden. Verwenden Sie unbedingt falsche Anmeldeinformationen, damit Sie sehen können, wie alles funktioniert.

Was machen wir?



Fertig machen

Wir beginnen mit dem Erstellen einer Dummy-Anwendung, die eine öffentliche und eine private Seite enthält. Die Root-URL ist die öffentliche Seite. Auf der öffentlichen Seite gibt es einen Login-Link. Wenn sich der Benutzer erfolgreich anmeldet, wird er auf die private Seite umgeleitet. Wenn nicht, werden sie zurück zum Anmeldeformular geleitet. Die private Seite zeigt den Benutzernamen. Wir verwenden dies als Ausgangspunkt für die Ajaxifizierung der Site.

Der erste Schritt besteht darin, mit dem Befehl "schienen" eine neue Anwendung zu generieren und anschließend authlogic zu installieren und einzurichten.

$ cd in-a-directory $ schienen unauffälliges login

Fügen Sie Authlogic hinzu.

# /config/environment.rb config.gem 'authlogic'

Nun installiere die Edelsteine.

$ sudo gem installieren gemcutter $ sudo gem tumble $ sudo rake gems: install

Erstellen Sie anschließend ein Benutzermodell und fügen Sie der Migration die erforderlichen Authlogic-Spalten hinzu.

$ ./script/generate model Benutzer existiert App / Modelle / existiert Test / Einheit / existiert Test / Fixtures / App / Modelle erstellen / user.rb create test / unit / user_test.rb erstellt test / fixtures / Benutzer.yml create db / migrate erstellt db / migrate / 20100102082657_create_users.rb

Fügen Sie nun die Spalten der neuen Migration hinzu.

Klasse 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 t.timestamps end end def self.down drop_table: Benutzer end end

Migrieren Sie die Datenbank.

$ rake db: migrieren

Beziehen Sie Authlogic in das Benutzermodell ein.

# /app/models/user.rb Klasse Benutzer < ActiveRecord::Base acts_as_authentic end

Jetzt können wir einen Benutzer anlegen. Da es sich um eine Demo-App handelt, sind keine webbasierten Funktionen für die Anmeldung erforderlich. Öffnen Sie also die Konsole und erstellen Sie einen Benutzer:

$ ./script/console >> me = User.create (: login => 'Adman65',: password => 'nettuts',: password_confirmation => 'nettuts')

Jetzt haben wir einen Benutzer im System, aber wir haben keine Möglichkeit, sich anzumelden oder abzumelden. Dazu müssen wir die Modelle, Controller und Ansichten erstellen. Authlogic hat eine eigene Klasse für die Protokollierung von Anmeldungen. Wir können den Generator dafür verwenden:

# Die Benutzersitzung $ ./script/generate UserSession erstellen

Als Nächstes müssen wir den Controller generieren, der Benutzer an- / abmeldet. Sie können Sitzungen wie jede andere Ressource in Rails erstellen.

# Erstellen Sie den Session Controller $ ./script/generate Controller UserSessions

Stellen Sie jetzt den Inhalt auf:

# /app/controllers/user_sessions_controller.rb Klasse 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 => : neues Ende Ende

Es sieht genauso aus wie ein Controller, der über ein Gerüst erzeugt wurde. Erstellen Sie nun den Benutzer-Controller mit öffentlichen und privaten Inhalten. Generieren Sie einen Benutzercontroller. Im Controller verwenden wir einen Filter vor, um den Zugriff auf die privaten Bereiche zu beschränken. Die Indexaktion ist öffentlich und die Show ist privat.

# Erstellen Sie die Benutzercontroller $ ./script/generate Controller-Benutzer

Aktualisieren Sie den Inhalt:

# /app/controllers/users_controller.rb Klasse UsersController < ApplicationController before_filter :login_required, :only => : show def index end def show @user = current_user end private def login_required, es sei denn current_user flash [: error] = 'Sie müssen angemeldet sein, um diese Seite anzuzeigen.' redirect_to new_user_session_path end end end

Sie sollten feststellen, dass current_user an diesem Punkt eine undefinierte Methode ist. Definieren Sie diese Methoden in ApplicationController. Öffnen Sie application_controller.rb und aktualisieren Sie den Inhalt:

# Anwendungscontroller-Klasse 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

Zu diesem Zeitpunkt sind die Modelle und Controller vollständig, die Ansichten jedoch nicht. Wir müssen Ansichten für ein Anmeldeformular und den öffentlichen und privaten Inhalt erstellen. Wir verwenden die intelligenten Generatoren, um ein einfaches Layout zu erstellen.

$ sudo gem installiere nifty-Generatoren $ ./script/generate nifty_layout

Zeit zum Erstellen des Anmeldeformulars. Wir werden ein Partial dafür verwenden, weil wir das Partial zukünftig dazu verwenden, nur das Anmeldeformular in der modalen Box zu rendern. Hier ist der Code zum Erstellen des Anmeldeformulars. Es ist genau so, als ob Sie einen Blogbeitrag oder ein anderes Modell erstellen würden.

# Erstellen Sie die Login-Ansichten # /app/views/user_sessions/_form.html.erb <% form_for(@user_session, :url => user_session_path) do | form | %> <%= form.error_messages %> 

<%= form.label :login %> <%= form.text_field :login %>

<%= form.label :password %> <%= form.password_field :password %>

<%= form.submit 'Login' %> <% end %>

Rendern Sie den Teil in der neuen Ansicht:

# /app/views/user_sessions/new.html.erb <% title 'Login Please' %> <%= render :partial => 'form'%>

Erstellen Sie einige grundlegende Seiten für den öffentlichen und privaten Inhalt. Die Indexaktion zeigt öffentlichen Inhalt und zeigt privaten Inhalt an.

# erstellt die Dummy-Public-Seite # /app/views/users/index.html.erb <% title 'Unobtrusive Login' %> 

Inhalt der Öffentlichkeit

<%= link_to 'Login', new_user_session_path %>

Und für die private Seite:

# Die Dummy-Privatseite erstellen # /app/views/users/show.html.erb <% title 'Welcome' %> 

Hallo <%=h @user.login %>

<%= link_to 'Logout', user_session_path, :method => : lösche%>

Löschen Sie die Datei /public/index.html und starten Sie den Server. Sie können sich jetzt bei der Anwendung an- und abmelden.

$ ./script/server

Hier sind einige Screenshots der Demoanwendung. Die erste ist die öffentliche Seite.

Nun das Anmeldeformular

Und die private Seite

Und schließlich wird der Zugriff verweigert, wenn Sie versuchen, http: // localhost: 3000 / user zu besuchen

Der AJAX-Anmeldeprozess

Bevor wir fortfahren, müssen wir verstehen, wie Server und Browser zusammenarbeiten, um diesen Prozess abzuschließen. Wir wissen, dass wir JavaScript für das modale Feld und den Server verwenden müssen, um die Anmeldungen zu überprüfen. Machen wir uns klar, wie das funktionieren wird. Der Benutzer klickt auf den Anmelde-Link. Daraufhin wird ein modales Feld mit dem Anmeldeformular angezeigt. Der Benutzer füllt das Formular aus und wird entweder auf die private Seite umgeleitet, oder das modale Feld wird mit einem neuen Anmeldeformular aktualisiert. Die nächste Frage ist, wie Sie die modale Box aktualisieren oder dem Browser mitteilen, was er tun soll, nachdem der Benutzer das Formular übermittelt hat. Rails hat respons_to-Blöcke. Mit respons_to können Sie dem Controller mitteilen, dass er unterschiedliche Inhalte wiedergeben soll, wenn der Benutzer XML, HTML, JavaScript, YAML usw. angefordert hat. Wenn der Benutzer das Formular sendet, kann der Server JavaScript zurückgeben, das im Browser ausgeführt wird. Wir verwenden dieses Rendering für ein neues Formular oder eine Weiterleitung. Bevor wir tiefer tauchen, gehen wir den Vorgang in der Reihenfolge durch.

  1. Benutzer wechselt zur öffentlichen Seite
  2. Der Benutzer klickt auf den Login-Link
  3. Modal Box wird angezeigt
  4. Benutzer füllt das Formular aus
  5. Das Formular wird an den Server gesendet
  6. Der Server gibt JavaScript zur Ausführung zurück
  7. Browser führt das JavaScript aus, das die modale Box entweder umleitet oder aktualisiert.

Das ist das hohe Niveau. Hier ist die Low-Level-Implementierung.

  1. Benutzer besucht die öffentliche Seite
  2. Die öffentliche Seite enthält JavaScript, das ausgeführt wird, wenn das DOM bereit ist und JavaScript an den Login-Link anfügt. Dieses javscript führt für etwas JavaScript ein XMLHTTPRequest (XHR von jetzt an) an den Server aus. Das JavaScript setzt den Inhalt der Modalbox auf das Formular-HTML. Das JavaScript macht auch etwas sehr Wichtiges. Es bindet die Übermittlungsaktion des Formulars an eine XHR mit POST-Daten an die Aktion des Formulars. Dadurch kann der Benutzer das Anmeldeformular in der modalen Box weiterhin ausfüllen.
  3. Modal Box hat jetzt das Formular und das erforderliche JavaScript
  4. Benutzer klickt auf "Login"
  5. Die Funktion submit () wird aufgerufen, die mit ihren Daten ein POST-XHR für die Aktion des Formulars ausführt.
  6. Der Server generiert entweder das JavaScript für das Formular oder die Weiterleitung
  7. Der Browser empfängt das JavaScript und führt es aus. Der Browser aktualisiert entweder die modale Box oder leitet den Benutzer über window.location um.

Einen Höhepunkt am AJAX Ready Controller nehmen

Sehen wir uns die neue Struktur für den UserSessions-Controller an.

Klasse 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 => : Weiterleitung # JavaScript, um die Weiterleitung zu erledigen, sonst wants.html render: new wants.js # Standardwerte für create.js.erb end end end private def select_layout (request.xhr?)? nil: Ende der Anwendung

Wie Sie sehen, ist die Struktur anders. In if wenn save oder else conditional wird mit response_to der korrekte Inhalt gerendert. want.xx wobei xx ein Inhaltstyp ist. Standardmäßig fordern Prototype und jQuery Text / JavaScript an. Dies entspricht Wanna.js. Wir sind bereit für den AJAX-Teil. Wir verwenden keine Plugins, außer solche für modale Boxen. Wir verwenden Facebox für jQuery und ModalBox für Prototype.

Prototyp

Rails hat Unterstützung für Prototyp eingebaut. Die JavaScript-Helfer der Rail sind Ruby-Funktionen, die JavaScript generieren, das Prototype verwendet. Diese Technik wird als RJS (Ruby JavaScript) bezeichnet. Ein Beispiel ist remote_form_for, das wie der Standard for_for arbeitet und fügt einige JS hinzu, die an onsubmit gebunden sind und das Formular mit seiner Methode und seinen Daten an das Formular sendet. Ich werde RJS in diesem Artikel nicht verwenden, da ich Vanilla JS demonstrieren möchte. Ich denke, durch die Verwendung von reinem JS und dem Wegfall der JS-Helfer wird der Artikel für weniger erfahrene Entwickler zugänglicher. Wenn Sie möchten, können Sie diese Schritte mit Hilfe von RJS / Prototype-Helfern problemlos ausführen.

Das Hinzufügen von Prototyp zur Anwendung ist sehr einfach. Bei Verwendung des Befehls "schienen" werden die Prototypdateien und die Skriptdateien in / public / JavaScripts erstellt. Die Aufnahme ist einfach. Öffnen Sie /app/views/layouts/application.erb und fügen Sie diese Zeile in das head-Tag ein:

<%= JavaScript_include_tag :defaults %>

JavaScript_include_tag erstellt Skript-Tags für Standarddateien in / public / JavaScripts, am wichtigsten prototype.js, effects.js und application.js. effects.js ist skizzenhaft. application.js ist eine Datei, die Sie verwenden können, um anwendungsspezifische JS zu erhalten. Jetzt brauchen wir ein modales Box-Plugin. Wir werden das nutzen. Es ist ein sehr schönes modales Box-Plugin, das von OSX inspiriert wurde. Die Quelle wird auf GitHub gehostet. Sie müssen also die Dateien in Ihrem Projektverzeichnis klonen und verschieben. Zum Beispiel:

$ cd code $ git clone git: //github.com/okonet/modalbox.git $ cd modalbox # verschiebt die Dateien in die richtigen Verzeichnisse. # modalbox.css in / public / stylesheets verschieben # modalbox.js in / public / JavaScripts verschieben # spinner.gif in / public / images verschieben

Fügen Sie nun die Stylesheets und JavaScript in Ihre Anwendung ein.

 <%= stylesheet_link_tag 'application' %> <%= stylesheet_link_tag 'modalbox' %> <%= JavaScript_include_tag :defaults %> <%= JavaScript_include_tag 'modalbox'%>

Nun rufen wir unseren Login-Link auf, um eine Modalbox zu öffnen. Zu diesem Zweck müssen wir JavaScript hinzufügen, das ausgeführt wird, wenn das DOM bereit ist und die Modalbox an unseren Link angehängt wird. Wenn der Benutzer auf den Login-Link klickt, führt der Browser ein GET nach / user_sessions / new aus, das das Login-Formular enthält. Der Login-Link verwendet die # Login-Link-Auswahl. Aktualisieren Sie den Login-Link, um die neue ID in /app/views/users/index.html.erb zu verwenden. Ändern Sie die Funktion link_to folgendermaßen:

<%= link_to 'Login', new_user_session_path, :id => 'login-link'%>

Das gibt uns einen # Login-Link. Nun zum JavaScript, um eine Modalbox anzufügen. Fügen Sie diese JS in /public/JavaScripts/application.js hinzu

document.observe ('dom: loaded', function () $ ('login-link'). observ ('click', function (event) event.stop (); Modalbox.show (this.href, title.) : 'Login', Breite: 500););)

Es gibt einige einfache JS, wenn der Benutzer auf den Link klickt, um ein modales Feld mit der Href des Links zu öffnen. Weitere Informationen finden Sie in der Dokumentation zu Modalbox. Hier ist ein Screenshot:

Beachten Sie, dass die Modalbox unserer Standardseite sehr ähnlich ist. Rails verwendet unser Anwendungslayout für alle HTML-Antworten. Da unsere XHRs HTML-Fragmente benötigen, ist es sinnvoll, ohne Layouts zu rendern. Beziehen Sie sich auf den Beispielcontroller. Ich habe eine Methode zur Bestimmung des Layouts eingeführt. Fügen Sie das UserSessionsController hinzu, um das Layout für XHRs zu deaktivieren.

Klasse 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] = "Abmeldung erfolgreich!" redirect_to root_path end private def select_layout (request.xhr?)? nil: Ende der Anwendung

Aktualisieren Sie die Seite und klicken Sie auf den Link, den Sie wie folgt erhalten sollten:

Füllen Sie das Formular aus und sehen Sie, was passiert. Wenn Sie das from mit ungültigen Informationen ausfüllen, werden Sie außerhalb des modalen Felds umgeleitet. Wenn Sie sich korrekt anmelden, werden Sie normalerweise weitergeleitet. Je nach Anforderung sollte der Benutzer das Formular immer wieder in der Modalbox ausfüllen können, bis er sich korrekt anmeldet. Wie können wir das schaffen? Wie zuvor beschrieben, müssen wir AJAX verwenden, um Daten an den Server zu senden. Anschließend können Sie die modale Box mit JavaScript mit dem Formular aktualisieren oder eine Umleitung durchführen. Wir wissen, dass die Modalbox GET für HTML ausführt. Nach der Anzeige der anfänglichen Modalbox müssen wir JS schreiben, durch das das Formular sich selbst im AJAX-Stil übergibt. Dadurch kann sich das Formular innerhalb der modalen Box einreichen. Das Hinzufügen dieses Codes nach dem Aufrufen des modalen Felds funktioniert nicht, da das XHR möglicherweise nicht abgeschlossen ist. Wir müssen den afterLoad-Callback von Modalbox verwenden. Hier ist der neue Code:

document.observe ('dom: loaded', function () $ ('login-link'). observ ('click', function (event) event.stop (); Modalbox.show (this.href, title.) : 'Login', Breite: 500, afterLoad: function () $ ('new_user_session'). Observ ('submit', function (event) event.stop (); this.request ();) ;)

Form # request ist eine bequeme Methode zum Serialisieren und Senden des Formulars über Ajax.Request an die URL des Aktionsattributs des Formulars - genau das, was wir wollen. Jetzt können Sie das Formular in der Modal ausfüllen, ohne es zu schließen. Die Client-Seite ist nun abgeschlossen. Was ist mit der Serverseite? Der Client sendet einen POST, der JS zurücksenden möchte. Der Server muss entweder JavaScript zurückgeben, um das Formular zu aktualisieren, oder eine Weiterleitung ausführen. Im UserSessionsController verwenden wir respons_to, um die JS-Anforderung zu bearbeiten, und eine Bedingung, um den korrekten JS zurückzugeben. Beginnen wir mit der Behandlung des fehlgeschlagenen Anmeldefalls. Der Server muss JS zurückgeben, der das Formular aktualisiert, und das neue Formular anweisen, über ajax zu senden. Diese Vorlage wird in /app/views/users_sessions/create.js.erb abgelegt. Hier ist die Struktur für die neue Aktion create:

def create @user_session = UserSession.new (params [: user_session]) wenn @ user_session.save flash [: notice] = "Anmeldung erfolgreich!" redirect_to user_path sonst respons_to | will | wants.html render: new wants.js # create.js.erb Ende Ende Ende

Füllen Sie jetzt create.js.erb aus:

$ ('MB_content'). Aktualisierung ("<%= escape_JavaScript(render :partial => 'form')%> "); Modalbox.resizeToContent (); $ ('new_user_session'). observ ('submit', function (event) event.stop (); this.request (););

Zuerst aktualisieren wir den Inhalt, um das neue Formular aufzunehmen. Dann ändern wir die Größe der modalen Box. Als Nächstes wird das Formular wie zuvor ajaxifiziert. Voilla, Sie können das Formular so oft ausfüllen, wie Sie möchten.

Als nächstes müssen wir den Umleitungsfall behandeln. Erstellen Sie eine neue Datei in /app/views/users_sessions/redirect.js.erb:

 window.location = "<%= user_path %>”;

Aktualisieren Sie nun die Erstellungsaktion, um den Umleitungsprozess auszuführen:

def create @user_session = UserSession.new (params [: user_session]), wenn @ user_session.save geantwortet_an | wants.html do flash [: notice] = "Login erfolgreich!" redirect_to user_path end wants.js render: redirect Ende sonst antworten, um zu tun | want | wants.html render: new wants.js # create.js.erb Ende Ende Ende

Und das ist es! Versuchen Sie nun, sich mit den korrekten Anmeldeinformationen anzumelden, und Sie werden zur privaten Seite weitergeleitet. Um weitere Informationen zu erhalten, versuchen Sie, einen Spinner hinzuzufügen und eine Benachrichtigung mitzuteilen, dass der Benutzer das Formular sendet oder umgeleitet wird. Die Anwendung funktioniert auch dann, wenn der Benutzer JavaScript deaktiviert hat.

jQuery

Da ich bereits über den Prototyp-Prozess berichtet habe, gehe ich nicht mehr auf die Details ein. Stattdessen werde ich schnell das alternative JavaScript beschreiben, das der Anwendung hinzugefügt werden soll. Die jQuery-Version hat dieselbe Struktur wie die Prototyp-Version. Alles, was wir ändern müssen, ist das, was in application.js, create.js.erb und JavaScript / css enthalten ist.

Als erstes müssen wir jQuery und Facebox herunterladen. Verschieben Sie jQuery in / public / JavaScripts als jquery.js. Für Facebox verschieben Sie die Bilder in / public / images /, Stylesheets in / public / stylesheets und schließlich die JS in / public / JavaScripts. Aktualisieren Sie nun /app/views/layouts/application.html.erb, um die Änderungen widerzuspiegeln:

 <%= 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 wird mit einem Standard-Stylesheet geliefert, das davon ausgeht, dass sich Ihre Bilder in / facebox befinden. Sie müssen diese Selektoren in facebox.css wie folgt aktualisieren:

#facebox .b Hintergrund: URL (/images/b.png);  #facebox .tl Hintergrund: URL (/images/tl.png);  #facebox .tr Hintergrund: URL (/images/tr.png);  #facebox .bl Hintergrund: URL (/images/bl.png);  #facebox .br Hintergrund: URL (/images/br.png); 

Jetzt fügen wir dem Login-Link die Facebox hinzu. Öffnen Sie /public/JavaScripts/application.js und verwenden Sie Folgendes:

$ (document) .ready (function () $ ('# login-link'). facebox (loadingImage: '/images/loading.gif', closeImage: '/images/closelabel.gif',); );

Ich überschreibe die Standardeinstellungen für die Bilder, um den neuen Bildpfad wiederzugeben. Starten Sie den Server und gehen Sie zur Indexseite. Sie sollten eine nette Facebox mit dem Anmeldeformular sehen:

Als nächstes müssen wir das Formular so einstellen, dass es sich selbst über AJAX einreicht. Wie zuvor müssen wir Callbacks verwenden, um Code auszuführen, nachdem die modale Box fertig ist. Wir verwenden die Post-Methode von jQuery für die XHR-Anfrage. Facebox hat einen After-Reveal-Hook, den wir verwenden können. application.js:

$ (document) .ready (function () $ ('# login-link'). facebox (loadingImage: '/images/loading.gif', closeImage: '/images/closelabel.gif',); $ (document) .bind ('decl.facebox', function () $ ('# new_user_session'). submit (function () $ .post (this.action, $ (this) .serialize (), null, ") script "); return false;);););

Die Aktualisierung von create.js.erb sollte einfach genug sein. Wir müssen den Inhalt der Facebox aktualisieren und das Formular erneut ajaxifizieren. Hier ist der Code:

$ ('# facebox .content'). html ("<%= escape_JavaScript(render :partial => 'form')%> "); $ ('# new_user_session'). submit (function () $ .post (this.action, $ (this) .serialize (), null," script "); return false; );

Und das ist es! Hier ist das Endprodukt:

Code herunterladen

Den Code erhalten Sie hier. Es gibt Verzweigungen für jede Bibliothek, so dass Sie die Prototype- oder jQuery-Versionen überprüfen können. Fragen, Kommentare, Bedenken? Nochmals vielen Dank für das Lesen!

  • Folgen Sie uns auf Twitter oder abonnieren Sie den Nettuts + RSS-Feed für die besten Webentwicklungs-Tutorials im Web.