Hur man använder Omniauth för att verifiera dina användare

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.


Steg 1: Förbereda din ansökan

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.


Steg 2: Skapa en leverantör

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.


Steg 3: Lägg till dina leverantörer till appen

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.


Steg 4: Skapa inloggningssidan

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:

  • Den första raden används för att skapa ett enkelt inloggningsformulär där användaren kommer att se en enkel? Anslut med Facebook? länk.
  • Den andra raden är att få leverantörens återuppringning. När en användare godkänner din app vidarebefordrar leverantören användaren till den här webbadressen, så vi kan utnyttja deras data.
  • Den sista kommer att användas när det finns ett problem, eller om användaren inte godkände vår ansökan.

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.


Steg 5: Skapa användarmodell

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.


Steg 6: Lägga lite logik till vår Sessions Controller

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:

  • Vi kontrollerar om det finns ett tillstånd för det leverantör och det uid. Om en finns, välkomnar vi vår användare tillbaka.
  • Om det inte finns något tillstånd, undertecknar vi användaren. Vi skapar en ny användare med namn och e-post som leverantören (Facebook i det här fallet) ger oss, och vi associerar en auktorisation med 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?.


Steg 7: Aktivera flera leverantörer

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:

  • Om användaren redan är inloggad lägger vi till den leverantör som de använder till sitt konto.
  • Om de inte är inloggade, försöker vi hitta en användare med den leverantören eller skapa en ny om det är nödvändigt.

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.


Steg 8: Några Extra Tweaks

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.


Slutsats

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!