Hoe Omniauth te gebruiken om uw gebruikers te authenticeren

Ik haat het om je aan te melden voor websites. Ik heb me al aangemeld voor zovelen, met verschillende gebruikersnamen, dat teruggaan naar een van hen en mijn geloofsbrieven proberen te onthouden soms onmogelijk is. Tegenwoordig zijn de meeste sites begonnen met het aanbieden van alternatieve manieren om je aan te melden, doordat je je Facebook, Twitter of zelfs je Google-account kunt gebruiken. Het creëren van een dergelijke integratie voelt soms als een lange en zware taak. Maar wees niet bang, Omniauth is hier om te helpen.

Met Omniauth kunt u eenvoudig meer dan zestig authenticatieproviders integreren, waaronder Facebook, Google, Twitter en GitHub. In deze zelfstudie ga ik uitleggen hoe deze verificatieproviders in uw app kunnen worden geïntegreerd.


Stap 1: uw applicatie voorbereiden

Laten we een nieuwe Rails-applicatie maken en de benodigde edelstenen toevoegen. Ik ga ervan uit dat je Ruby en Ruby op Rails 3.1 al hebt geïnstalleerd met behulp van RubyGems.

 rails nieuwe omniauth-tutorial

Open nu je Gemfile en verwijs naar het omniauth-juweel.

 gem 'omniauth'

Vervolgens voer je per gewoon de bundel installeren commando om het juweel te installeren.


Stap 2: een provider maken

Als u een provider aan Omniauth wilt toevoegen, moet u zich aanmelden als ontwikkelaar op de site van de provider. Nadat u zich hebt aangemeld, krijgt u twee strings (een soort van gebruikersnaam en een wachtwoord) die moeten worden doorgegeven aan Omniauth. Als u een OpenID-provider gebruikt, hebt u alleen de URL OpenID nodig.

Als u Facebook-authenticatie wilt gebruiken, ga dan naar developers.facebook.com/apps en klik op? Nieuwe app maken?.

Vul alle benodigde informatie in en kopieer, eenmaal klaar, de ID van je app en geheim.

Twitter configureren is een beetje ingewikkelder op een ontwikkelmachine, omdat ze je niet toestaan ​​om? Localhost te gebruiken? als een domein voor callbacks. Het configureren van uw ontwikkelomgeving voor dit soort dingen valt buiten het bestek van deze zelfstudie. Ik raad echter aan dat u Pow gebruikt als u op een Mac werkt.


Stap 3: voeg uw providers toe aan de app

Maak een nieuw bestand onder config / initialiseerders riep omniauth.rb. We gaan onze authenticatieproviders configureren via dit bestand.

Plak de volgende code in het bestand dat we eerder hebben gemaakt:

 Rails.application.config.middleware.use OmniAuth :: Builder-provider: Facebook, YOUR_APP_ID, YOUR_APP_SECRET einde

Dit is echt de configuratie die u nodig hebt om dit op gang te krijgen. De rest wordt verzorgd door Omniauth, zoals we in de volgende stap zullen vinden.


Stap 4: De aanmeldingspagina maken

Laten we onze sessiecontroller maken. Voer de volgende code in uw terminal uit om een ​​nieuwe te maken sessies controller en de nieuwe, creëren, en mislukking acties.

rails genereren controller-sessies maken nieuwe fout

Open vervolgens je config / routes.rb bestand en voeg dit toe:

 get '/ login',: to => 'sessions # new',: as =>: login match '/ auth /: provider / callback',: to => 'sessions # create' match '/ auth / failure', : to => 'session # failure'

Laten we dit opsplitsen:

  • De eerste regel wordt gebruikt om een ​​eenvoudig inlogformulier te maken waarbij de gebruiker een eenvoudige ziet? Verbind met Facebook? link.
  • De tweede regel is om de callback van de provider te onderscheppen. Nadat een gebruiker uw app heeft geautoriseerd, leidt de provider de gebruiker om naar deze URL, zodat we gebruik kunnen maken van hun gegevens.
  • De laatste wordt gebruikt als er een probleem is of als de gebruiker onze toepassing niet heeft geautoriseerd.

Zorg ervoor dat u de routes verwijdert die automatisch zijn gemaakt toen u de rails genereren commando. Ze zijn niet nodig voor ons kleine project.

Open je app / controllers / sessions_controller.rb bestand en schrijf de creëren methode, zoals zo:

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

Dit wordt gebruikt om te zorgen dat alles werkt. Wijs je browser naar localhost: 3000 / auth / facebook en je wordt doorgestuurd naar Facebook zodat je je app kunt autoriseren (best wel goed?). Autoriseer het en je wordt teruggeleid naar je app en ziet een hash met wat informatie. Daartussenin zal je je naam, je Facebook-gebruikers-ID en je e-mail bevinden, onder andere.


Stap 5: Het gebruikersmodel maken

De volgende stap is om een ​​gebruikersmodel te maken zodat gebruikers zich kunnen aanmelden met hun Facebook-accounts. In de Rails-console (rails console), maakt u het nieuwe model.

rails genereren model Gebruikersnaam: string email: string

Voor nu onze gebruiker model- zal alleen een hebben naam en een e-mail. Met dat uit de weg, hebben we een manier nodig om de gebruiker te herkennen bij de volgende keer dat ze inloggen. Houd er rekening mee dat we hier geen velden in het gebruikersmodel voor hebben.

Het idee achter een applicatie zoals die we proberen te bouwen is dat een gebruiker kan kiezen tussen Facebook of Twitter (of een andere provider) om zich aan te melden, dus we hebben een ander model nodig om die informatie op te slaan. Laten we het maken:

rails genereren model Autorisatieprovider: string uid: string user_id: integer

Een gebruiker heeft een of meer autorisaties en wanneer iemand probeert in te loggen met een provider, kijken we eenvoudig naar de autorisaties in de database en zoeken naar een die overeenkomt met de uid en leverancier velden. Op deze manier stellen we gebruikers ook in staat om veel providers te hebben, zodat ze later kunnen inloggen via Facebook of Twitter of elke andere provider die ze hebben geconfigureerd!

Voeg de volgende code toe aan uw app / modellen / user.rb het dossier:

 has_many: autorisaties valideert: name,: email,: presence => true

Dit geeft aan dat a gebruiker kan meerdere autorisaties hebben, en dat de naam en e-mail velden in de database zijn vereist.

Volgende, naar jouw app / modellen / authorization.rb bestand, voeg toe:

 belong_to: gebruiker valideert: provider,: uid,: presence => true

Binnen dit model wijzen we erop dat elke autorisatie gebonden is aan een specifiek gebruiker. We stellen ook een aantal validaties in.


Stap 6: een beetje logica toevoegen aan onze Sessions Controller

Laten we wat code toevoegen aan onze sessies controleur zodat het een gebruiker registreert in of aanmeldt, afhankelijk van de situatie. Open app / controllers / sessions_controller.rb en wijzig de creëren methode, zoals zo:

 def create auth_hash = request.env ['omniauth.auth'] @authorization = Authorization.find_by_provider_and_uid (auth_hash ["provider"], auth_hash ["uid"]) als @autorization render: text => "Welcome back # @ authorisation .user.name! U heeft zich al aangemeld. " else user = 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 =>" Hallo # user.name! Je hebt je aangemeld. " einde

Deze code heeft duidelijk wat refactoring nodig, maar daar gaan we later op in. Laten we het eerst beoordelen:

  • We controleren of daarvoor een machtiging bestaat leverancier en dat uid. Als er een bestaat, verwelkomen we onze gebruiker terug.
  • Als er geen autorisatie bestaat, ondertekenen we de gebruiker. We maken een nieuwe gebruiker met de naam en e-mail die de provider (Facebook in dit geval) ons geeft, en we koppelen een autorisatie aan de leverancier en de uid we zijn gegeven.

Geef het een test! Ga naar localhost: 3000 / auth / facebook en je zou moeten zien? Je hebt je aangemeld ?. Als u de pagina vernieuwt, ziet u nu? Welkom terug?.


Stap 7: Meerdere providers inschakelen

Het ideale scenario zou zijn om een ​​gebruiker toe te staan ​​zich aan te melden via een provider en later een andere provider toe te voegen zodat hij meerdere opties heeft om in te loggen. Onze app staat dat voorlopig niet toe. We moeten onze code een beetje refactoren. Verander jouw sessions_controlller.rb's creëren methode om er zo uit te zien:

 def create auth_hash = request.env ['omniauth.auth'] als sessie [: user_id] # Betekent dat onze gebruiker is ingelogd. Voeg de autorisatie toe aan de gebruiker User.find (sessie [: user_id]) add_provider (auth_hash) render : text => "Je kunt nu inloggen met # auth_hash [" provider "]. kapitaliseer ook!" else # Log in of registreer hem auth = Authorization.find_or_create (auth_hash) # Maak de sessie sessie [: user_id] = auth.user.id render: text => "Welcome # auth.user.name!" einde

Laten we dit eens bekijken:

  • Als de gebruiker al is ingelogd, voegen we de provider die zij gebruiken toe aan zijn account.
  • Als ze niet zijn aangemeld, gaan we proberen een gebruiker bij die provider te vinden of een nieuwe maken als dit nodig is.

Om de bovenstaande code te laten werken, moeten we een aantal methoden toevoegen aan onze Gebruiker en machtiging modellen. Open user.rb en voeg de volgende methode toe:

 def add_provider (auth_hash) # Controleer of de provider al bestaat, dus we voegen deze niet tweemaal toe tenzij authorizations.find_by_provider_and_uid (auth_hash ["provider"], auth_hash ["uid"]) Authorization.create: user => self,: provider => auth_hash ["provider"],: uid => auth_hash ["uid"] einde

Als de gebruiker deze provider nog niet heeft gekoppeld aan zijn account, gaan we door en voegen we deze toe - eenvoudig. Voeg deze methode nu toe aan uw authorization.rb het dossier:

 def self.find_or_create (auth_hash) tenzij auth = find_by_provider_and_uid (auth_hash ["provider"], auth_hash ["uid"]) user = User.create: name => auth_hash ["user_info"] ["name"],: email = > auth_hash ["user_info"] ["email"] auth = create: user => user,: provider => auth_hash ["provider"],: uid => auth_hash ["uid"] end auth end

In de bovenstaande code proberen we een autorisatie te vinden die overeenkomt met het verzoek. Als dit niet lukt, maken we een nieuwe gebruiker.

Als u dit lokaal wilt proberen, heeft u een tweede authenticatieprovider nodig. Je zou het OAuth-systeem van Twitter kunnen gebruiken, maar, zoals ik al eerder zei, je zult een andere aanpak moeten gebruiken, aangezien Twitter het gebruik van? Localhost niet toestaat? als het domein van de callback-URL (het werkt in ieder geval niet voor mij). Je kunt ook proberen je code te hosten op Heroku, wat perfect is voor een eenvoudige site zoals die we maken.


Stap 8: Enkele extra aanpassingen

Ten slotte moeten we gebruikers natuurlijk de mogelijkheid bieden om uit te loggen. Voeg dit stuk code toe aan uw sessiecontroller:

 def destroy session [: user_id] = nil render: text => "U bent uitgelogd!" einde

We moeten ook de toepasselijke route maken (in routes.rb).

 get '/ logout',: to => 'sessions # destroy'

Zo simpel is het! Als u naar localhost: 3000 / logout bladert, moet uw sessie worden gewist en wordt u uitgelogd. Dit maakt het gemakkelijker om meerdere accounts en providers te proberen. We moeten ook een bericht toevoegen dat wordt weergegeven wanneer gebruikers de toegang tot onze app weigeren. Als je dit onthoudt, hebben we deze route aan het begin van de zelfstudie toegevoegd. Nu hoeven we alleen de methode toe te voegen in de sessies controller:

 def failure render: text => "Sorry, maar u stond geen toegang toe tot onze app!" einde

En last but not least, maak de inlogpagina aan, waar de gebruiker op kan klikken? Verbind met Facebook? link. Open app / views / sessies / new.html.erb en voeg toe:

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

Als je naar localhost: 3000 / login gaat, zie je een link die je doorverwijst naar de Facebook-authenticatiepagina.


Conclusie

Ik hoop dat dit artikel je een kort voorbeeld geeft van hoe Omniauth werkt. Het is een behoorlijk krachtige edelsteen en je kunt websites maken waarvoor gebruikers zich niet hoeven aan te melden, wat altijd een pluspunt is! Je kunt over Omniauth leren op GitHub.

Laat het ons weten als je nog vragen hebt!