Torii je odlehčená autentizační knihovna pro Ember.js. Podporuje různé poskytovatele OAuth (jako je Twitter, Google nebo FaceBook) a lze jej použít k implementaci přesměrování OAuth založeného na vyskakovacích oknech. Používá správce relací (pro udržování aktuálního uživatele) a adaptéry (pro zachování stavu autentizace).
V tomto článku ukážu, jak implementovat přihlášení pomocí Twitteru a jak zacházet s uživatelskými relacemi s Torii. Twitter používá pro ověřování OAuth 1.0a, které nevyžaduje mnoho nastavení na straně klienta (pouze vyskakovací okno a správa relace). Vyžaduje to však významnou komponentu na straně serveru, pro kterou budu používat Sinatru.
Pro ty, kteří chtějí pokračovat, můžete získat kód, který bude doprovázet tento článek z GitHubu.
Nastavení aplikace na Twitteru
Pokud je chcete sledovat, budete si také muset nastavit aplikaci na Twitteru. Můžete to udělat tak, že přejdete na http://apps.twitter.com, kde kliknete na „Vytvořit novou aplikaci“. Poté vyplňte své údaje a nezapomeňte zadat http://127.0.0.1:9292
do pole URL zpětného volání (za předpokladu, že testujete lokálně).
Po vytvoření aplikace budete přesměrováni na stránku s nastavením aplikace. Klikněte na kartu „Klíče a přístupové tokeny“ a poznamenejte si svůj zákaznický klíč a své zákaznické tajemství.
Nastavení serveru
To vyžaduje malou znalost toho, jak OAuth 1.0a funguje (pokud byste si chtěli zopakovat, můžete se podívat na dokumentaci na webu Twitteru). Vyžaduje také knihovnu, která podporuje ověřování s různými poskytovateli OAuth. Protože používáme Sinatru, OmniAuth je vynikající volbou (je postaven na Racku, takže bude fungovat téměř v jakékoli webové aplikaci Ruby). Pokud bychom používali Node, mohli jsme místo toho zvolit Passport.
Namísto toho, abyste vás prováděli nastavením serveru, můžete jednoduše vzít pracovní kopii aplikace a spustit ji sami. Zde je postup:
git clone https://github.com/sitepoint-editors/torii-twitter-example.git
cd torii-twitter-example
Poté do svého terminálu přidejte svůj zákaznický klíč a své zákaznické tajemství do svého prostředí
export TWITTER_KEY=twitter_key TWITTER_SECRET=twitter_secret
Spusťte bundle
pro instalaci všech závislostí (za předpokladu, že máte nainstalovanou Ruby), pak rake db:migrate
k nastavení databáze.
Poté musíte sestavit aplikaci Ember:
cd public
npm install && bower install
ember build
Nakonec spusťte rackup
spusťte Sinatru a přejděte na http://127.0.0.1:9292
. Pokud vše proběhlo podle plánu, měli byste být schopni se přihlásit ke své nové aplikaci pomocí Twitteru.
Všimněte si, že koncové body serveru jsou následující:
Neověřený uživatel:
get '/auth/twitter'
:Spustí proces přihlášení, požádá o token z Twitteru, přesměruje uživatele na Twitter za účelem ověření.get '/auth/twitter/callback'
:Twitter ověří a odešle token zde, server vymění token za přístupový token a ověří uživatele.
Ověřený uživatel:
post '/logout'
:Vymaže ověření uživatele.get '/users/me'
:Vrátí ověřené informace o uživateli.
Nyní se pomocí naší aplikace podíváme na to, jak byste mohli implementovat Torii do svých vlastních projektů.
Instalovat Torii
Nejprve nastavte projekt Ember pomocí Ember CLI a nainstalujte Torii (náš je nainstalován v public
složka):
ember init
npm install –save-dev torii
Konfigurace poskytovatele
Dále přidejte poskytovatele Twitteru a nastavte requestTokenUri
do koncového bodu serveru, kde tok začíná:/auth/twitter
. Nastavte také sessionServiceName: 'session'
pro nastavení správce relací.
config/environment.js
ENV.torii = {
sessionServiceName: 'session',
providers: {
'twitter': {
requestTokenUri: '/auth/twitter'
}
}
};
Torii má několik vestavěných poskytovatelů, ale vytváření vlastních je navrženo tak, aby bylo snadné.
Přihlásit se
Dále nastavte šablonu přihlášení. Pokud je uživatel ověřen, ukažte jeho uživatelské jméno a odkaz pro odhlášení. Pokud nejsou ověřeni, ukažte odkaz na přihlášení. Dává smysl to vložit do application
šablony, aby byla viditelná na každé trase.
app/templates/application.hbs
{{#if session.isWorking }}
Working..
{{else}}
{{#if session.isAuthenticated }}
<p>Welcome {{session.currentUser.name}}
<a href="#" {{action 'logout'}}>Logout</a>
</p>
{{else}}
<a href="#" {{action 'signInViaTwitter'}}>Login via Twitter</a>
{{/if}}
{{/if}}
session
vlastnost je vložena Torriho správcem relace a odhaluje několik užitečných vlastností. session.isWorking
je pravda mezi takovými přechody stavů jako opening
na authenticated
nebo closing
na unauthenticated
. Nepoužívejte session
mezi přechody, ale místo toho zobrazit pruh načítání. session.currentUser
je ověřený uživatel – je nastaven adaptérem.
Poté definujte signInViaTwitter
akci, která otevře vyskakovací okno a spustí proces přihlášení OAuth.
app/routes/login.js
actions: {
signInViaTwitter: function() {
var route = this;
this.get('session').open('twitter').then(function() {
route.transitionTo('index');
}, function() {
console.log('auth failed');
});
}
}
Všimněte si, že this.get('session').open('twitter')
vrátí příslib, který je vyřešen poté, co ověří uživatele, což zase zavře vyskakovací okno a nastaví relaci. Jakmile je uživatelská relace navázána, přejde na cestu indexu, zatímco pokud selže, nedělá nic.
Pokud uživatel obnoví prohlížeč nebo jej poprvé otevře, zatímco je relace aktivní, aplikace by měla načíst existující relaci a pokračovat, jako by se uživatel již přihlásil. Nakonec, pokud se uživatel odhlásí, relace by měla být zničena .
app/routes/application.js
export default Ember.Route.extend({
beforeModel: function() {
return this.get('session').fetch().then(function() {
console.log('session fetched');
}, function() {
console.log('no session to fetch');
});
},
actions: {
logout: function() {
this.get('session').close();
}
}
});
Zde this.get('session').fetch()
načte existující relaci a nastaví uživatele jako ověřeného. Umístíme to do beforeModel
háček, takže aplikace počká, dokud nebude uživatel načten, než se vykreslí. Jak můžete očekávat, this.get('session').close()
zavře relaci – což se stane, když uživatel klikne na „Odhlásit“.
Správa relací a adaptér
Adaptér Torii zpracovává ověření serveru a spravuje relaci uživatele třemi metodami, open
, fetch
a close
. Jsou ve složce app/torii-adapters
. Výchozí nastavení je aplikační adaptér, který rozšiřuje Ember.Object
.
open
metoda vytvoří relaci. Dělá to, když náš server odešle ověřovací token do aplikace Ember (přes přesměrování vyskakovacího okna) s code
parametr, například /?code=authentication_code
. Toto code
je analyzován Torii a předán našemu adaptéru v auth
parametr. Stručný popis toku:
- Torii otevře vyskakovací okno na
/auth/twitter
. - Server přesměrovává na Twitter.
- Uživatel se ověřuje pomocí Twitteru.
- Twitter přesměrovává na
/auth/twitter/callback
. - Server ověří uživatele a vygeneruje přístupový token.
- Server přesměrovává na naši aplikaci Ember s přístupovým tokenem, např.:
/?code=access_token
- Torii zavře vyskakovací okno, analyzuje kód a předá jej adaptéru.
Jakmile je token k dispozici, je umístěn do místního úložiště a je nastavena autorizační hlavička pro požadavky Ajax. Ověřený uživatel je načten odesláním požadavku Ajax na users/me
a uloženy v relaci.
app/torii-adapters/application.js
open: function(auth) {
if (!auth.code) {
return rejectPromise();
}
localStorage.token = auth.code;
var adapter = this.container.lookup('adapter:application');
adapter.set('headers', { 'Authorization': localStorage.token });
return this.get('store').find('user', 'me').then(function(user) {
return {
currentUser: user
};
});
},
auth
parametr obsahuje kód – pokud není dostupný, příslib je odmítnut a ověření se nezdaří. Způsob, jak nastavit záhlaví pro Ember Data, je použít this.container.lookup
najít adapter:application
a nastavte záhlaví na tomto adaptéru. this.get('store').find('user', 'me')
odešle požadavek na users/me
, před objekt s currentUser
je vrácena vlastnost (nastavená na ověřeného uživatele). Torii to přidá do session
objekt, který vloží do všech tras, takže bude dostupný v šablonách.
Poznámka :Chcete-li odeslat požadavek proti users/me
, budete muset definovat uživatelský model pomocí Ember CLI koncový bod s daty Ember:
ember g model user name:string token:string
fetch
metoda zkontroluje existující token v místním úložišti. Pokud existuje, načte token a nastaví relaci. To udržuje uživatele ověřeného mezi aktualizacemi stránky, pokud je token platný a zůstává v místním úložišti.
fetch: function() {
if (!localStorage.token) {
return rejectPromise();
}
var adapter = this.container.lookup('adapter:application');
adapter.set('headers', { 'Authorization': localStorage.token });
return this.get('store').find('user', 'me').then(function(user) {
return {
currentUser: user
};
});
},
Způsob načtení ověřeného uživatele s tokenem je načíst uživatele z users/me
. Torii je agnostik ohledně toho, jak udržovat relace, pokud poskytujete logiku prostřednictvím háčků adaptéru. Neváhejte se podělit o jakékoli alternativní metody, které můžete mít.
Nakonec close
metoda uzavře relaci. Odebere token z místního úložiště a vytvoří post /logout
Požadavek Ajax na server, který zneplatní přístupový token.
close: function() {
var authToken = localStorage.token;
localStorage.token = null;
var adapter = this.container.lookup('adapter:application');
adapter.set('headers', { 'Authorization': authToken });
return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax({
url: '/logout',
headers: {
'Authorization': authToken
},
type: 'POST',
success: Ember.run.bind(null, resolve),
error: Ember.run.bind(null, reject)
});
});
}
Závěr
Chvíli mi trvalo, než jsem pochopil, jak by mělo fungovat ověřování u jednostránkové aplikace, nemluvě o tom, jak funguje OAuth. To platí zejména v případě, že aplikace komunikuje s REST API, které má být bezstavové, a proto není k dispozici žádná relace na straně serveru, která by uživatele udržela. Takže preferuji autentizaci založenou na tokenech. Ember bohužel v takových návodech chybí, takže pokud se chcete dozvědět více, měli byste hledat jiné frameworky, jako je AngularJS.
Zde je několik dalších informací, které by se vám mohly hodit:
- Ověřování založené na tokenech pomocí AngularJS
- Token versus ověřování založené na souborech cookie
- Ověření pomocí AngularJS
- Ověření GitHub pomocí Torii
- Webové tokeny JSON
- Satellizer, AngularJS verze Torii