Přidejte ověřování Twitteru do aplikace Ember.js s Torii

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:

  1. Torii otevře vyskakovací okno na /auth/twitter .
  2. Server přesměrovává na Twitter.
  3. Uživatel se ověřuje pomocí Twitteru.
  4. Twitter přesměrovává na /auth/twitter/callback .
  5. Server ověří uživatele a vygeneruje přístupový token.
  6. Server přesměrovává na naši aplikaci Ember s přístupovým tokenem, např.:/?code=access_token
  7. 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