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.
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.
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.
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.
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:
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.
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.
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:
leverancier
en dat uid
. Als er een bestaat, verwelkomen we onze gebruiker terug.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?.
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:
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.
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.
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!