Jag hatar att registrera mig för webbplatser. Jag har redan anmält mig för så många, med olika användarnamn, som går tillbaka till en av dem och försöker komma ihåg mina uppgifter är ibland omöjliga. Idag har de flesta webbplatser börjat erbjuda alternativa sätt att anmäla sig, genom att låta dig använda din Facebook, Twitter eller till och med ditt Google-konto. Att skapa en sådan integration känns ibland som en lång och svår uppgift. Men frukta inte, Omniauth är här för att hjälpa.
Omniauth låter dig enkelt integrera mer än sextio autentiseringsleverantörer, inklusive Facebook, Google, Twitter och GitHub. I den här handledningen ska jag förklara hur jag integrerar dessa autentiseringsleverantörer i din app.
Låt oss skapa en ny Rails-applikation och lägga till de nödvändiga ädelstenarna. Jag antar att du redan har installerat Ruby och Ruby on Rails 3.1 med RubyGems.
skenar ny omniauth-handledning
Öppna nu din Gemfile
och hänvisa omniauth pärlan.
pärla "omniauth"
Därefter kör du vanligt buntinstallation
kommandot för att installera pärlan.
För att lägga till en leverantör till Omniauth måste du registrera dig som utvecklare på leverantörens webbplats. När du har anmält dig får du två strängar (typ av ett användarnamn och ett lösenord), som måste vidarebefordras till Omniauth. Om du använder en OpenID-leverantör, behöver du bara OpenID-webbadressen.
Om du vill använda Facebook-autentisering, gå vidare till developers.facebook.com/apps och klicka på? Skapa ny app?.
Fyll i all nödvändig information, och när du är klar kopierar du Appens ID och hemlighet.
Konfigurering av Twitter är lite mer komplicerat på en utvecklingsmaskin, eftersom de inte tillåter dig att använda? Localhost? som en domän för callbacks. Att konfigurera din utvecklingsmiljö för denna typ av sak ligger utanför ramen för denna handledning, men jag rekommenderar att du använder Pow om du är på en Mac.
Skapa en ny fil under config / initializers
kallad omniauth.rb
. Vi ska konfigurera våra autentiseringsleverantörer genom den här filen.
Klistra in följande kod i filen vi skapade tidigare:
Rails.application.config.middleware.use OmniAuth :: Builder gör leverantör: facebook, YOUR_APP_ID, YOUR_APP_SECRET slutet
Detta är ärligt all konfiguration du behöver för att få det här. Resten tas om hand av Omniauth, som vi kommer att hitta i nästa steg.
Låt oss skapa vår styrning av sessioner. Kör följande kod i din terminal för att skapa en ny sessioner
controller, och ny
, skapa
, och fel
åtgärder.
skenor genererar kontroller sessioner nytt skapa misslyckande
Öppna sedan din config / routes.rb
fil och lägg till det här:
få '/ login',: till => 'sessioner # ny',: som =>: inloggnings match '/ auth /: provider / callback',: till => 'sessioner # skapa' match '/ auth / fail' : till => 'sessioner # misslyckande'
Låt oss bryta ner det här:
Se till att du raderar de rutter som skapades automatiskt när du körde skenor genererar
kommando. De är inte nödvändiga för vårt lilla projekt.
Öppna din app / controllers / sessions_controller.rb
fil och skriv skapa
metod, som så:
def skapa auth_hash = request.env ['omniauth.auth'] render: text => auth_hash.inspect end
Detta används för att se till att allt fungerar. Peka din webbläsare till localhost: 3000 / auth / facebook och du kommer att omdirigeras till Facebook så att du kan godkänna din app (ganska cool va?). Godkänn det, och du kommer att omdirigeras tillbaka till din app och se en hash med viss information. Däremot blir ditt namn, ditt Facebook-användar-ID och ditt email, bland annat.
Nästa steg är att skapa en användarmodell så att användare kan registrera sig med sina Facebook-konton. I Rails-konsolen (rails konsolen
), skapa den nya modellen.
rails generera modell Användarnamn: string email: string
För nu, vår användare modell
kommer bara ha a namn
och en e-post
. Med det ur vägen behöver vi ett sätt att känna igen användaren nästa gång de loggar in. Tänk på att vi inte har några fält på vår användares modell för detta ändamål.
Tanken bakom en applikation som den vi försöker bygga är att en användare kan välja mellan att använda Facebook eller Twitter (eller någon annan leverantör) att anmäla sig, så vi behöver en annan modell för att lagra den informationen. Låt oss skapa det:
rails generera modell Auktorisationsleverantör: sträng uid: sträng user_id: heltal
En användare kommer att ha en eller flera tillstånd, och när någon försöker logga in med en leverantör tittar vi bara på auktorisationerna i databasen och letar efter en som matchar uid
och leverantör
fält. På så sätt kan vi också få många leverantörer, så de kan senare logga in med Facebook eller Twitter eller någon annan leverantör som de har konfigurerat!
Lägg till följande kod till din app / modeller / user.rb
fil:
has_many: auktorisationer validerar: namn,: email,: presence => true
Detta anger att a användare
kan ha flera tillstånd, och att namn
och e-post
Fält i databasen krävs.
Därefter till din app / modeller / authorization.rb
fil, lägg till:
belongs_to: user validates: provider,: uid,: presence => true
Inom denna modell betecknar vi att varje auktorisation är bunden till en specifik användare
. Vi ställer också in någon validering.
Låt oss lägga till en kod till våra sessioner kontrollant
så att det loggar in en användare eller registrerar dem, beroende på fallet. Öppna app / controllers / sessions_controller.rb
och modifiera skapa
metod, som så:
def skapa auth_hash = request.env ['omniauth.auth'] @ authorization = Authorization.find_by_provider_and_uid (auth_hash ["provider"], auth_hash ["uid"]) om @authorization render: text => "Välkommen tillbaka # @ authorization .user.name! Du har redan anmält dig. " annan användare = User.new: name => auth_hash ["user_info"] ["name"],: email => auth_hash ["user_info"] ["email"] user.authorizations.build: provider => auth_hash ["provider "],: uid => auth_hash [" uid "] user.save render: text =>" Hej # user.name! Du har registrerat dig. " änden
Denna kod behöver klart en del refactoring, men vi kommer att ta itu med det senare. Låt oss granska det först:
leverantör
och det uid
. Om en finns, välkomnar vi vår användare tillbaka.leverantör
och den uid
gavs.Ge det ett test! Gå till localhost: 3000 / auth / facebook och du bör se? Du har anmält dig ?. Om du uppdaterar sidan ska du nu se? Välkommen tillbaka?.
Det ideala scenariot skulle vara att tillåta en användare att registrera sig med en leverantör och senare lägga till en annan leverantör så att han kan ha flera alternativ att logga in med. Vår app tillåter inte det för nu. Vi behöver refactor vår kod lite. Ändra din sessions_controlller.rb
's skapa
metod att se så här ut:
def skapa auth_hash = request.env ['omniauth.auth'] om session [: user_id] # betyder att användaren är inloggad. Lägg till auktorisationen för användaren User.find (session [: user_id]). add_provider (auth_hash) render : text => "Du kan nu logga in med # auth_hash [" provider "]. capitalize too!" annars # Logga in eller logga in auth = Authorization.find_or_create (auth_hash) # Skapa session session [: user_id] = auth.user.id render: text => "Välkommen # auth.user.name!" änden
Låt oss granska det här:
För att ovanstående kod ska fungera måste vi lägga till några metoder till vår Användare
och Tillstånd
modeller. Öppna user.rb
och lägg till följande metod:
def add_provider (auth_hash) # Kontrollera om leverantören redan finns, så vi lägger inte till den två gånger om inte authorizations.find_by_provider_and_uid (auth_hash ["provider"], auth_hash ["uid"]) Authorization.create: user => self provider => auth_hash ["provider"],: uid => auth_hash ["uid"] änden
Om användaren inte redan har den här leverantören kopplad till sitt konto kommer vi att fortsätta och lägga till det - enkelt. Lägg nu till den här metoden till din authorization.rb
fil:
def self.find_or_create (auth_hash) om inte auth = find_by_provider_and_uid (auth_hash ["provider"], auth_hash ["uid"]) användare = User.create: name => auth_hash ["user_info"] ["namn"],: email = > auth_hash ["user_info"] ["email"] auth = skapa: användare => användare,: provider => auth_hash ["provider"],: uid => auth_hash ["uid"] end auth end
I koden ovan försöker vi hitta en auktorisation som matchar begäran, och om vi inte lyckas skapar vi en ny användare.
Om du vill prova det här lokalt behöver du en andra autentiseringsleverantör. Du kan använda Twitters OAuth-system, men som jag påpekade förut måste du använda ett annat tillvägagångssätt, eftersom Twitter inte tillåter att använda? Localhost? som återuppringningsadressens domän (åtminstone det fungerar inte för mig). Du kan också försöka vara värd för din kod på Heroku, vilket är perfekt för en enkel webbplats som den vi skapar.
Slutligen måste vi naturligtvis tillåta användare att logga ut. Lägg till den här koden till din sessions controller:
def förstöra session [: user_id] = nil render: text => "Du har loggat ut!" slutet
Vi måste också skapa den tillämpliga rutten (i routes.rb
).
få '/ logout',: till => 'sessioner # förstör'
Så enkelt är det! Om du bläddrar till localhost: 3000 / logout, bör din session rensas, och du kommer att loggas ut. Detta gör det enklare att prova flera konton och leverantörer. Vi måste även lägga till ett meddelande som visas när användare nekar åtkomst till vår app. Om du kommer ihåg, lade vi till denna rutt nära början av handledningen. Nu behöver vi bara lägga till metoden i sessioner
kontrollant:
def fel gör: text => "Tyvärr, men du gav inte tillgång till vår app!" slutet
Och sist men inte minst, skapa inloggningssidan, där användaren kan klicka på "Connect With Facebook"? länk. Öppna app / vyer / sessions / new.html.erb
och lägg till:
<%= link_to "Connect With Facebook", "/auth/facebook" %>
Om du går till localhost: 3000 / login kommer du att se en länk som omdirigerar dig till facebook-autentiseringssidan.
Jag hoppas att den här artikeln har gett dig ett kort exempel på hur Omniauth fungerar. Det är en väldigt kraftfull pärla, och låter dig skapa webbplatser som inte kräver att användarna registrerar sig, vilket alltid är ett plus! Du kan lära dig om Omniauth på GitHub.
Låt mig veta om du har några frågor!