Slik bruker du Omniauth til å godkjenne brukerne

Jeg hater å registrere meg for nettsteder. Jeg har allerede registrert meg for så mange, ved hjelp av forskjellige brukernavn, som går tilbake til en av dem og prøver å huske legitimasjonene mine er noen ganger umulig. Disse dager har de fleste nettsteder begynt å tilby alternative måter å registrere seg på, ved å la deg bruke Facebook, Twitter eller til og med Google-kontoen din. Å skape en slik integrasjon føles noen ganger som en lang og vanskelig oppgave. Men frykt ikke, Omniauth er her for å hjelpe.

Omniauth lar deg enkelt integrere mer enn seksti autentiseringsleverandører, inkludert Facebook, Google, Twitter og GitHub. I denne opplæringen skal jeg forklare hvordan du integrerer disse autentiseringsleverandørene i appen din.


Trinn 1: Klargjør programmet

La oss lage et nytt Rails-program og legge til de nødvendige edelstenene. Jeg kommer til å anta at du allerede har installert Ruby og Ruby on Rails 3.1 ved hjelp av RubyGems.

 skinner ny omniauth-opplæring

Åpne nå din Gemfile og referer til omniauth-perlen.

 perle 'omniauth'

Deretter kjører du som vanlig bunt installasjon kommandoen for å installere perlen.


Trinn 2: Opprette en leverandør

For å legge til en leverandør til Omniauth, må du registrere deg som utvikler på leverandørens nettsted. Når du har registrert deg, får du to strenger (for eksempel et brukernavn og et passord), som må sendes videre til Omniauth. Hvis du bruker en OpenID-leverandør, er alt du trenger, OpenID-nettadressen.

Hvis du vil bruke Facebook-godkjenning, gå over til developers.facebook.com/apps og klikk på? Opprett ny app?.

Fyll ut all nødvendig informasjon, og når du er ferdig, kopier du Appens ID og Hemmelig.

Konfigurere Twitter er litt mer komplisert på en utviklingsmaskin, siden de ikke tillater deg å bruke? Localhost? som et domene for tilbakeringinger. Konfigurer ditt utviklingsmiljø for denne typen ting er utenfor omfanget av denne opplæringen, men jeg anbefaler at du bruker Pow hvis du er på en Mac.


Trinn 3: Legg til leverandørene dine i appen

Opprett en ny fil under config / initializers kalt omniauth.rb. Vi skal konfigurere våre autentiseringsleverandører gjennom denne filen.

Lim inn følgende kode i filen vi opprettet tidligere:

 Rails.application.config.middleware.use OmniAuth :: Builder gjør leverandør: facebook, YOUR_APP_ID, YOUR_APP_SECRET slutten

Dette er ærlig all konfigurasjon du trenger for å få dette til å gå. Resten blir tatt vare på av Omniauth, som vi skal finne i neste trinn.


Trinn 4: Opprette innloggingssiden

La oss lage vår sesjonskontroller. Kjør følgende kode i terminalen din for å opprette en ny økter kontrolleren og ny, skape, og svikt handlinger.

skinner genererer kontroller-økter, oppretter ny feil

Deretter åpner du config / routes.rb fil og legg til dette:

 få '/ logg inn':: til => 'økter # ny',: som =>: innloggingskamp '/ auth /: leverandør / tilbakeringing',: til => 'økter # skape' samsvar '/ auth / feil' : til => 'økter # feil'

La oss bryte dette ned:

  • Den første linjen brukes til å lage et enkelt påloggingsskjema hvor brukeren vil se en enkel? Koble til Facebook? link.
  • Den andre linjen er å fange leverandørens tilbakeringing. Etter at en bruker har godkjent appen, overfører leverandøren brukeren til denne nettadressen, slik at vi kan benytte seg av deres data.
  • Den siste vil bli brukt når det er et problem, eller hvis brukeren ikke godkjente programmet vårt.

Pass på at du sletter ruter som ble opprettet automatisk når du kjørte skinner generere kommando. De er ikke nødvendige for vårt lille prosjekt.

Åpne din app / kontrollere / sessions_controller.rb fil og skriv skape metode, slik som:

 def lage auth_hash = request.env ['omniauth.auth'] render: text => auth_hash.inspect ende

Dette brukes til å sikre at alt fungerer. Pek nettleseren din til localhost: 3000 / auth / facebook, og du blir omdirigert til Facebook, slik at du kan autorisere appen din (ganske kult, hva?). Tillat det, og du vil bli omdirigert tilbake til appen din og se en hash med litt informasjon. Mellom vil bli ditt navn, ditt Facebook bruker ID, og ​​din e-post, blant annet.


Trinn 5: Opprette brukermodellen

Det neste trinnet er å opprette en brukermodell slik at brukerne kan registrere seg ved hjelp av deres Facebook-kontoer. I Rails-konsollen (skinner konsoll), opprett den nye modellen.

skinner generere modell Brukernavn: streng e-post: streng

For nå, vår bruker modell vil bare ha a Navn og en e-post. Med det ut av veien, trenger vi en måte å gjenkjenne brukeren neste gang de logger inn. Husk at vi ikke har noen felt på brukerens modell til dette formålet.

Ideen bak et program som det vi prøver å bygge er at en bruker kan velge mellom å bruke Facebook eller Twitter (eller annen leverandør) til å registrere seg, så vi trenger en annen modell for å lagre den informasjonen. La oss lage det:

skinner generere modell Autorisasjonsleverandør: streng uid: streng user_id: heltall

En bruker vil ha en eller flere tillatelser, og når noen prøver å logge inn ved hjelp av en leverandør, ser vi bare på autorisasjonene i databasen og ser etter en som samsvarer med uid og forsørger Enger. På denne måten aktiverer vi også brukere å ha mange leverandører, så de kan senere logge inn med Facebook, eller Twitter, eller noen annen leverandør de har konfigurert!

Legg til følgende kode i din app / modeller / user.rb fil:

 has_many: autorisasjoner validerer: navn,: e-post,: tilstedeværelse => sant

Dette angir at a bruker kan ha flere godkjenninger, og at Navn og e-post felt i databasen er påkrevd.

Deretter til din app / modeller / authorization.rb fil, legg til:

 belongs_to: user validates: provider,: uid,: presence => true

Innenfor denne modellen betegner vi at hver autorisasjon er bundet til et bestemt bruker. Vi stiller også noen validering.


Trinn 6: Legge litt av logikk til vår sesjonskontroller

La oss legge til noen koden til våre økter kontrolleren slik at det logger en bruker inn eller registrerer dem, avhengig av saken. Åpen app / kontrollere / sessions_controller.rb og endre skape metode, slik som:

 def lage auth_hash = request.env ['omniauth.auth'] @ authorization = Authorization.find_by_provider_and_uid (auth_hash ["provider"], auth_hash ["uid"]) hvis @authorization gjengir: text => "Velkommen tilbake # @ autorisasjon .user.name! Du har allerede registrert deg. " ellers bruker = User.new: name => auth_hash ["user_info"] ["name"],: email => auth_hash ["user_info"] ["email"] user.authorizations.build: provider => auth_hash "],: uid => auth_hash [" uid "] user.save gjengir: text =>" Hei # user.name! Du har registrert deg. " slutten

Denne koden trenger tydeligvis noen refactoring, men vi skal håndtere det senere. La oss først vurdere det først:

  • Vi kontrollerer om det finnes en autorisasjon for det forsørger og det uid. Hvis en eksisterer, gleder vi oss tilbake til brukeren.
  • Hvis det ikke finnes noen autorisasjon, signerer vi brukeren opp. Vi lager en ny bruker med navnet og e-posten som leverandøren (Facebook i dette tilfellet) gir oss, og vi forbinder en autorisasjon med forsørger og uid ble gitt.

Gi det en prøve! Gå til localhost: 3000 / auth / facebook, og du bør se? Du har registrert deg ?. Hvis du oppdaterer siden, bør du nå se? Velkommen tilbake?.


Trinn 7: Aktiverer flere leverandører

Det ideelle scenariet ville være å la en bruker registrere seg ved hjelp av en leverandør, og senere legge til en annen leverandør, slik at han kan ha flere alternativer for å logge inn med. Vår app tillater ikke det for nå. Vi må refactor vår kode litt. Forandre din sessions_controlller.rb's skape metode for å se slik ut:

 def lage auth_hash = request.env ['omniauth.auth'] hvis økt [: user_id] # Betyr brukeren vår er logget inn. Legg til autorisasjonen til brukeren User.find (økt [: user_id]). add_provider (auth_hash) gjengir : text => "Du kan nå logge inn med # auth_hash [" provider "]. kapitalisere også!" ellers # Logg inn eller logg deg opp auth = Authorization.find_or_create (auth_hash) # Opprett økt økt [: user_id] = auth.user.id render: text => "Velkommen # auth.user.name!" slutten

La oss se på dette:

  • Hvis brukeren allerede er logget inn, skal vi legge til leverandøren de bruker til kontoen sin.
  • Hvis de ikke er logget inn, skal vi prøve å finne en bruker hos den leverandøren, eller opprette en ny hvis det er nødvendig.

For at koden ovenfor skal virke, må vi legge til noen metoder for vår Bruker og Autorisasjon modeller. Åpen user.rb og legg til følgende metode:

 def add_provider (auth_hash) # Sjekk om leverandøren allerede eksisterer, så vi legger ikke til det to ganger, med mindre autorizations.find_by_provider_and_uid (auth_hash ["provider"], auth_hash ["uid"]) Authorization.create: user => self,: provider => auth_hash ["provider"],: uid => auth_hash ["uid"] slutten

Hvis brukeren ikke allerede har denne leverandøren knyttet til sin konto, vil vi fortsette og legge til det - enkelt. Legg nå denne metoden til din authorization.rb fil:

 def self.find_or_create (auth_hash) med mindre auth = find_by_provider_and_uid (auth_hash ["provider"], auth_hash ["uid"]) bruker = User.create: name => auth_hash ["user_info"] ["navn"], > auth_hash ["user_info"] ["email"] auth = opprett: bruker => bruker,: provider => auth_hash ["provider"],: uid => auth_hash ["uid"] end auth end

I koden ovenfor prøver vi å finne en autorisasjon som samsvarer med forespørselen, og hvis vi ikke lykkes, oppretter vi en ny bruker.

Hvis du vil prøve dette ut lokalt, trenger du en annen godkjenningsleverandør. Du kan bruke Twitters OAuth-system, men som jeg påpekte før, må du bruke en annen tilnærming, siden Twitter ikke tillater bruk av? Localhost? som tilbakekallingsadressens domenenavn (i det minste virker det ikke for meg). Du kan også prøve å hoste koden på Heroku, som er perfekt for et enkelt nettsted som det vi lager.


Trinn 8: Noen ekstra tweaks

Til slutt må vi selvsagt tillate brukere å logge ut. Legg til dette stykket kode til sessjonskontrolleren din:

 def destroy session [: user_id] = nil render: text => "Du har logget ut!" slutt

Vi må også lage den aktuelle ruten (i routes.rb).

 få '/ logout',: til => 'økter # ødelegge'

Det er så enkelt! Hvis du surfer til localhost: 3000 / logout, bør økten din slettes, og du vil bli logget ut. Dette vil gjøre det enklere å prøve flere kontoer og tilbydere. Vi må også legge til en melding som vises når brukere nekter tilgang til appen vår. Hvis du husker, la vi denne ruten nær begynnelsen av opplæringen. Nå trenger vi bare å legge til metoden i økter kontrolleren:

 def feil gjør: text => "Beklager, men du tillot ikke tilgang til vår app!" slutt

Og sist men ikke minst, opprett innloggingssiden, der brukeren kan klikke på? Koble med Facebook? link. Åpen app / visninger / økter / new.html.erb og legg til:

 <%= link_to "Connect With Facebook", "/auth/facebook" %>

Hvis du går til localhost: 3000 / login vil du se en lenke som vil omdirigere deg til Facebook-autentiseringssiden.


Konklusjon

Jeg håper denne artikkelen har gitt deg et kort eksempel på hvordan Omniauth fungerer. Det er en betydelig kraftig perle, og lar deg lage nettsteder som ikke krever at brukerne registrerer seg, noe som alltid er et pluss! Du kan lære om Omniauth på GitHub.

Gi meg beskjed hvis du har spørsmål!