Et diskret innloggingssystem er en som kommer ut av brukerens måte. Det vil gjøre søknaden din finere og mer polert. Denne artikkelen vil veilede deg gjennom prosessen med å sette opp brukerlogger, og deretter ajaxify prosessen ved å flytte skjemaet til en modal boks som kommuniserer med serveren. I tillegg vil denne artikkelen vise deg hvordan du oppretter oppsettet ved hjelp av jQuery og Prototype, slik at du kan velge ditt favorittbibliotek. Denne artikkelen antar at du har erfaring med Rails og jQuery eller Prototype.
Du kan bruke Adman65 / nett for en vellykket innlogging. Pass på at du bruker dårlige legitimasjon, slik at du kan se hvordan alt fungerer.
Vi skal begynne med å lage et dummy-program som har en offentlig og privat side. Roten url er den offentlige siden. Det er en innloggingskobling på den offentlige siden. Hvis brukeren logger seg inn, blir de omdirigert til den private siden. Hvis ikke, blir de omdirigert tilbake til påloggingsskjemaet. Den private siden viser brukernavnet. Vi bruker dette som utgangspunkt for å ajaxify nettstedet.
Det første trinnet er å bruke rails-kommandoen for å generere et nytt program, og deretter installere og sette opp authlogic.
$ cd til-a-katalog $ rails diskret-logg inn
Legg til authlogic.
# /config/environment.rb config.gem 'authlogic'
Installer nå edelstenene.
$ sudo perle installasjon gemcutter $ sudo perle tommel $ sudo rake gems: installere
Deretter oppretter du en brukermodell og legger til de nødvendige autologiske kolonnene for overføringen.
$ ./script/generate model Brukeren eksisterer app / modeller / eksisterer test / enhet / eksisterer test / inventar / lager app / models / user.rb lage test / enhet / user_test.rb lage test / inventar / users.yml lage db / migrere opprett db / migrere / 20100102082657_create_users.rb
Legg til kolonnene i den nye overføringen.
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 endeendelen def self.down drop_table:
Migrere databasen.
$ rake db: migrere
Inkluder authlogic i brukermodellen.
# /app/models/user.rb klasse Bruker < ActiveRecord::Base acts_as_authentic end
Nå kan vi lage en bruker. Siden dette er en demo-app, er ikke webbasert funksjonalitet for påmelding nødvendig. Så åpne konsollen og opprett en bruker:
$ ./script/console >> me = User.create (: login => 'Adman65',: passord => 'netts',: password_confirmation => 'nettutsalg')
Nå har vi en bruker i systemet, men vi har ingen måte å logge inn eller logge ut. Vi må opprette modellene, kontrollerne og visningene for dette. Authlogic har sin egen klasse for å spore pålogginger. Vi kan bruke generatoren for det:
# opprett brukerøkten $ ./script/generate UserSession
Deretter må vi generere kontrolleren som vil logge inn / logge ut brukere. Du kan opprette økter som alle andre ressurser i Rails.
# opprett øktkontrollen $ ./script/generate controller UserSessions
Sett nå innholdet til:
# /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 => : Ny sluttendens ende
Det ser ut akkurat som en kontroller som ble generert via stillas. Opprett nå brukerens kontroller som har offentlig og privat innhold. Generer en brukerens kontroller. Inne i kontrolleren bruker vi et før filter for å begrense tilgangen til de private områdene. Indekshandlingen er offentlig og showet er privat.
# opprett brukerens kontroller $ ./script/generate controller brukere
Oppdater innholdet:
# /app/controllers/users_controller.rb klasse UsersController < ApplicationController before_filter :login_required, :only => : vis def index end def vis @user = current_user end privat def login_required med mindre current_user flash [: error] = 'Du må være logget inn for å vise denne siden.' redirect_to new_user_session_path slutten slutten
Du bør legge merke til at current_user er en udefinert metode på dette punktet. Definer disse metodene i ApplicationController. Åpne applikasjonscontroller.rb og oppdater innholdet:
# Application Controller 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
På dette tidspunktet er modellene og kontrollerne ferdige, men visninger er ikke. Vi må opprette visninger for et påloggingsskjema og det offentlige og private innholdet. Vi bruker nifty-generators perlen for å lage en grunnleggende layout.
$ sudo perle installere nifty-generatorer $ ./script/generate nifty_layout
Tid til å opprette påloggingsskjemaet. Vi skal bruke en delvis for dette fordi vi i fremtiden vil bruke partiet til å gjengi bare innloggingsskjemaet i modalboksen. Her er koden for å opprette påloggingsskjemaet. Det er akkurat det samme som om du opprettet et blogginnlegg eller en annen modell.
# opprett innloggingsvisninger # /app/views/user_sessions/_form.html.erb <% form_for(@user_session, :url => user_session_path) gjør | form | %> <%= form.error_messages %><%= form.label :login %> <%= form.text_field :login %>
<%= form.label :password %> <%= form.password_field :password %>
<%= form.submit 'Login' %> <% end %>
Sett partiet i den nye visningen:
# /app/views/user_sessions/new.html.erb <% title 'Login Please' %> <%= render :partial => 'form'%>
Lag noen grunnleggende sider for det offentlige og private innholdet. Indekshandlingen viser offentlig innhold og viser viser privat innhold.
# opprett den offentlige nettsiden # /app/views/users/index.html.erb <% title 'Unobtrusive Login' %>Offentlig innvendig innhold
<%= link_to 'Login', new_user_session_path %>
Og for den private siden:
# opprett dummy privat side # /app/views/users/show.html.erb <% title 'Welcome' %>Hallo <%=h @user.login %>
<%= link_to 'Logout', user_session_path, :method => : slett%>
Slett filen /public/index.html og start serveren. Du kan nå logge inn og logge ut av programmet.
$ ./script/server
Her er noen skjermbilder av demo-applikasjonen. Den første er den offentlige siden.
Nå er påloggingsskjemaet
Og den private siden
Og til slutt nektes tilgang når du prøver å besøke http: // localhost: 3000 / user
Før vi fortsetter, må vi forstå hvordan serveren og nettleseren skal jobbe sammen for å fullføre denne prosessen. Vi vet at vi må bruke litt JavaScript for modalboksen og serveren for å validere pålogginger. La oss være klare på hvordan dette skal fungere. Brukeren klikker på innloggingslenken, og deretter vises en modal boks med påloggingsskjemaet. Brukeren fyller ut skjemaet og blir enten omdirigert til den private siden, eller modalboksen oppdateres med et nytt påloggingsskjema. Det neste spørsmålet er hvordan oppdaterer du modalboksen eller forteller nettleseren hva du skal gjøre etter at brukeren har sendt skjemaet? Rails har response_to blokker. Med respons_to kan du fortelle kontrolleren å gjøre annet innhold hvis brukeren ba om XML, HTML, JavaScript, YAML osv. Så når brukeren sender skjemaet, kan serveren returnere noen JavaScript til å utføre i nettleseren. Vi bruker dette til å gjengi et nytt skjema eller en omdirigering. Før du dykker noe dypere, la oss gå over prosessen i orden.
Det er det høye nivået. Her er implementeringen på lav nivå.
La oss ta en titt på den nye strukturen for UserSessions-kontrolleren.
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 => : omdirigering # JavaScript for å gjøre omadresseringsendoen, annet svar_for å gjøre | ønsker | wants.html render: new wants.js # standard for å create.js.erb slutten slutten privat def choose_layout (request.xhr?)? null: "slutt" på applikasjonen
Som du kan se er strukturen annerledes. På innsiden av hvis lagre, ellers betinget, er respons_to brukt til å gjøre det riktige innholdet. want.xx hvor xx er en innholdstype. Som standard Prototype og jQuery be om tekst / JavaScript. Dette tilsvarer wants.js. Vi er klar til å komme i gang på AJAX-delen. Vi vil ikke bruke noen plugins bortsett fra de for modale bokser. Vi bruker Facebox for jQuery og ModalBox for Prototype.
Rails har innebygd støtte for Prototype. Jernbanens JavaScript-hjelpere er Ruby-funksjoner som genererer JavaScript som bruker Prototype. Denne teknikken er kjent som RJS (Ruby JavaScript). Et eksempel er remote_form_for som fungerer som standard for_for legger til at noen JS er bundet til onsubmit som sender til skjemaet til handlingen ved hjelp av metoden med dataene. Jeg vil ikke bruke RJS i denne artikkelen siden jeg vil demonstrere vanilje JS. Jeg tror ved å bruke ren JS og eliminere JS-hjelperne, vil artikkelen bli mer tilnærmet av mindre erfarne utviklere. Når det er sagt, kan du enkelt utføre disse trinnene ved hjelp av RJS / Prototype-hjelpere hvis du velger.
Å legge Prototype til programmet er veldig enkelt. Når du bruker rails-kommandoen, oppretter den Prototype og scriptaculous-filer i / offentlige / JavaScripts. Inkluderende dem er enkelt. Åpne /app/views/layouts/application.erb og legg til denne linjen inne i hodetiketten:
<%= JavaScript_include_tag :defaults %>
JavaScript_include_tag lager skriptkoder for standardfiler i / offentlige / JavaScripts, viktigst prototype.js, effects.js og application.js. effects.js er scriptaculous. application.js er en fil du kan bruke til å beholde programspesifikke JS. Nå trenger vi en modal box plugin. Vi skal bruke dette. Det er en veldig fin modal boks plugin inspirert av OSX. Kilden er vert på GitHub, så du må klone og flytte filene i prosjektkatalogen. For eksempel:
$ cd kode $ git klon git: //github.com/okonet/modalbox.git $ cd modalbox # flytt filene i de riktige katalogene. # flytt modalbox.css inn / public / stylesheets # flytt modalbox.js inn / public / JavaScripts # flytt spinner.gif til / offentlig / bilder
Nå inkluderer stilark og JavaScript i søknaden din.
<%= stylesheet_link_tag 'application' %> <%= stylesheet_link_tag 'modalbox' %> <%= JavaScript_include_tag :defaults %> <%= JavaScript_include_tag 'modalbox'%>
La oss nå få innloggingslenken vår for å åpne en modalboks. For å gjøre dette må vi legge til noe JavaScript som kjører når DOM er klart som fester modalboksen til vår lenke. Når brukeren klikker på innloggingskoblingen, vil nettleseren gjøre en GET til / user_sessions / new som inneholder påloggingsskjemaet. Innloggingslenken bruker # innloggingslinkvelgeren. Oppdater innloggingslenken for å bruke det nye ID-nummeret i /app/views/users/index.html.erb. Endre linken til å fungere slik:
<%= link_to 'Login', new_user_session_path, :id => 'login-link'%>
Det gir oss en # login-link. Nå for JavaScript å legge ved en modalboks. Legg til denne JS i /public/JavaScripts/application.js
document.observe ('dom: loaded', funksjon () $ ('login-link'). observere ('klikk', funksjon (hendelse) event.stop (); Modalbox.show (this.href, title : 'Logg inn', bredde: 500););)
Det er noen enkle JS for når brukeren klikker på lenken, åpnes en modalboks med linkens href. Se dokumentasjonen for modalboks hvis du vil ha mer tilpasning. Her er et skjermbilde:
Legg merke til at inne i modalboksen ser veldig ut som vår standardside. Rails bruker vår applikasjonslayout for alle HTML-svar. Siden våre XHRs ønsker HTML-fragmenter, er det fornuftig å gjengi uten oppsett. Henvis til eksempelkontrolleren. Jeg introduserte en metode for å bestemme utformingen. Legg det til UserSessionsController for å deaktivere layout for XHRs.
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 => : Ny ende ende def ødelegge current_user_session.destroy flash [: notice] = "Logout vellykket!" redirect_to root_path end privat def select_layout (request.xhr?)? null: "slutt" på applikasjonen
Oppdater siden og klikk på linken du bør få noe slikt:
Fyll ut skjemaet og se hva som skjer. Hvis du fyller ut fra med dårlig info, blir du omdirigert utenfor modalboksen. Hvis du logger inn riktig, blir du omdirigert normalt. I henhold til kravene skal brukeren kunne fylle ut skjemaet igjen og igjen inne i modalboksen til de logger inn på riktig måte. Hvordan kan vi oppnå dette? Som beskrevet før må vi bruke AJAX til å sende inn data til serveren, og bruk deretter JavaScript for å oppdatere modalboksen med skjemaet eller omdirigere. Vi vet at modalboxen gjør en GET for HTML. Etter å ha vist den opprinnelige modalboxen, må vi skrive JS som gjør skjemaet sender seg AJAX-stil. Dette gjør at skjemaet kan sendes inn i modalboksen. Bare å legge til denne koden etter at modalboksen heter, vil ikke fungere fordi XHR kanskje ikke er ferdig. Vi må bruke Modalbox's afterLoad tilbakeringing. Her er den nye koden:
document.observe ('dom: loaded', funksjon () $ ('login-link'). observere ('klikk', funksjon (hendelse) event.stop (); Modalbox.show (this.href, title : 'Logg inn', bredde: 500, afterLoad: function () $ ('new_user_session'). Observer ('send', funksjon (hendelse) event.stop (); this.request ();) ;);)
Form # -forespørsel er en praktisk metode for serialisering og innlevering av skjemaet via en Ajax.Request til nettadressen til skjemaets handlingsattributt-som er akkurat det vi ønsker. Nå kan du fylle ut skjemaet inne i modal uten at det lukkes. Klientsiden er nå fullført. Hva med server siden? Klienten sender inn en POST som ønsker JS tilbake. Serveren må bestemme seg for å enten returnere JavaScript for å oppdatere skjemaet eller gjøre omdirigering. I UserSessionsController bruker vi respond_to for å håndtere JS-forespørselen og betinget av å returnere riktig JS. La oss begynne med å håndtere det mislykkede login-saken. Serveren må returnere JS som oppdaterer skjemaet, og forteller det nye skjemaet å sende inn over ajax. Vi plasserer denne malen i /app/views/users_sessions/create.js.erb. Her er strukturen for den nye skapeaksjonen:
def opprett @user_session = UserSession.new (params [: user_session]) hvis @ user_session.save flash [: notice] = "Logg inn vellykket!" redirect_to user_path else respond_to do | ønsker | wants.html render: new wants.js # create.js.erb slutten slutten
La oss nå fylle ut create.js.erb:
$ ( 'MB_content'). Oppdatering ("<%= escape_JavaScript(render :partial => 'form')%> "); Modalbox.resizeToContent (); $ ('new_user_session'). observere ('send', funksjon (hendelse) event.stop (); this.request (););
Først oppdaterer vi innholdet for å inkludere det nye skjemaet. Da endrer vi størrelsen på modalboksen. Neste ajaxify vi skjemaet som før. Voilla, du kan fylle ut skjemaet så mange ganger du vil.
Deretter må vi håndtere omadresseringssaken. Opprett en ny fil i /app/views/users_sessions/redirect.js.erb:
window.location =”<%= user_path %>“;
Oppdater nå opprettingsaksjonen for å håndtere omadresseringsprosessen:
def opprett @user_session = UserSession.new (params [: user_session]) hvis @ user_session.save respond_to do | ønsker | wants.html do flash [: notice] = "Logg inn vellykket!" redirect_to user_path end wants.js gjengi: omdirigere end else respond_to do | wishes | wants.html render: new wants.js # create.js.erb slutten slutten
Og det er det! Prøv nå innlogging med riktige legitimasjonsbeskrivelser, og du blir omdirigert til den private siden. For ytterligere læring, prøv å legge til en spinner og varsel for å fortelle brukeren skjemaet sender inn, eller de blir omdirigert. Programmet fungerer fortsatt hvis brukeren har JavaScript deaktivert også.
Siden jeg allerede har dekket prototypeprosessen, så vil jeg ikke gå inn i samme detalj som før. I stedet vil jeg bevege meg raskt og beskrive det alternative JavaScript for å legge til i programmet. JQuery vesion vil ha nøyaktig samme struktur som Prototype-versjonen. Alt vi trenger å endre er hva som er i application.js, create.js.erb, og JavaScript / css inkluderer.
Første ting vi trenger å gjøre er å laste ned jQuery og Facebox. Flytt jQuery til / offentlig / JavaScripts som jquery.js. For facebox flytte bildene til / public / images /, stylesheets til / public / stylesheets, og til slutt JS inn / public / JavaScripts. Oppdater nå /app/views/layouts/application.html.erb for å gjenspeile endringene:
<%= 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 leveres med standard stilark som forutsetter at du har bildene dine i / facebox. Du må oppdatere disse valgene i facebox.css slik:
#facebox .b bakgrunn: url (/images/b.png); #facebox .tl bakgrunn: url (/images/tl.png); #facebox .tr bakgrunn: url (/images/tr.png); #facebox .bl bakgrunn: url (/images/bl.png); #facebox .br bakgrunn: url (/images/br.png);
Nå knytter vi ansiktsboksen til påloggingslenken. Åpne /public/JavaScripts/application.js og bruk dette:
$ (dokument) .ready (funksjon () $ ('# login-link'). facebox (loadingImage: '/images/loading.gif', closeImage: '/images/closelabel.gif',); );
Jeg overstyrer standardinnstillingene for bildene for å gjenspeile den nye bildebanen. Start sever og gå over til indekssiden. Du bør se et fint ansiktskasse med påloggingsskjemaet:
Neste ting vi må gjøre er å sette skjemaet til å sende seg inn via AJAX. Akkurat som før må vi bruke tilbakeringinger til å utføre kode etter at modalboksen er klar. Vi bruker jQuerys innleggsmetode for XHR-forespørselen. Facebox har en etter avsløret krok vi kan bruke. application.js:
$ (dokument) .ready (funksjon () $ ('# login-link'). facebox (loadingImage: '/images/loading.gif', closeImage: '/images/closelabel.gif',); $ (dokument) .bind ('reveal.facebox', funksjon () $ ('# new_user_session'). send (funksjon () $ .post (this.action, $ (dette) .serialize (), null, " skript "); return false;);););
Oppdatere create.js.erb bør være lett nok. Vi må oppdatere innholdsrammens innhold og omforme skjemaet. Her er koden:
$ ('# facebox .content'). html ("<%= escape_JavaScript(render :partial => "form")%> "); $ ('# new_user_session'). send (funksjon () $ .post (denne.aksjonen, $ (denne) .serialize (), null," script "); return false; );
Og det er det! Her er sluttproduktet:
Du kan få koden her. Det er grener for hvert bibliotek, slik at du kan sjekke ut prototypen eller jQuery-versjonene. Eventuelle spørsmål, kommentarer, bekymringer? Takk igjen for å lese!