Auth0をシングルページアプリケーションに組み込む方法がより簡単になりました! #Auth0JP

105件のシェア(ちょっぴり話題の記事)

auth0-spa-js が正式リリース!

認証基盤サービス(IDaaS)であるAuth0。最近は国内でもかなり認知度が上がってきたように思います。

Auth0をシングルページアプリケーションに組み込む方法は、今まで auth0.js を使う方法が一般的でしたが、つい先日シングルページアプリケーションでの利用に特化したモジュール auth0-spa-js が正式リリースされました。

どこが簡単になったの?

Auth0のReactサンプルアプリケーションである auth0-react-samples の認証部分の実装コードを見ていただけると一目瞭然です。

以前は以下のような感じのコードを、アプリケーション実装側で用意する必要がありました。

import history from '../history';
import auth0 from 'auth0-js';
import { AUTH_CONFIG } from './auth0-variables';

export default class Auth {
  accessToken;
  idToken;
  expiresAt;

  auth0 = new auth0.WebAuth({
    domain: AUTH_CONFIG.domain,
    clientID: AUTH_CONFIG.clientId,
    redirectUri: AUTH_CONFIG.callbackUrl,
    responseType: 'token id_token',
    scope: 'openid'
  });

  constructor() {
    this.login = this.login.bind(this);
    this.logout = this.logout.bind(this);
    this.handleAuthentication = this.handleAuthentication.bind(this);
    this.isAuthenticated = this.isAuthenticated.bind(this);
    this.getAccessToken = this.getAccessToken.bind(this);
    this.getIdToken = this.getIdToken.bind(this);
    this.renewSession = this.renewSession.bind(this);
  }

  login() {
    this.auth0.authorize();
  }

  handleAuthentication() {
    this.auth0.parseHash((err, authResult) => {
      if (authResult && authResult.accessToken && authResult.idToken) {
        this.setSession(authResult);
      } else if (err) {
        history.replace('/home');
        console.log(err);
        alert(`Error: ${err.error}. Check the console for further details.`);
      }
    });
  }

  getAccessToken() {
    return this.accessToken;
  }

  getIdToken() {
    return this.idToken;
  }

  setSession(authResult) {
    // Set isLoggedIn flag in localStorage
    localStorage.setItem('isLoggedIn', 'true');

    // Set the time that the access token will expire at
    let expiresAt = (authResult.expiresIn * 1000) + new Date().getTime();
    this.accessToken = authResult.accessToken;
    this.idToken = authResult.idToken;
    this.expiresAt = expiresAt;

    // navigate to the home route
    history.replace('/home');
  }

  renewSession() {
    this.auth0.checkSession({}, (err, authResult) => {
       if (authResult && authResult.accessToken && authResult.idToken) {
         this.setSession(authResult);
       } else if (err) {
         this.logout();
         console.log(err);
         alert(`Could not get a new token (${err.error}: ${err.error_description}).`);
       }
    });
  }

  logout() {
    // Remove tokens and expiry time
    this.accessToken = null;
    this.idToken = null;
    this.expiresAt = 0;

    // Remove isLoggedIn flag from localStorage
    localStorage.removeItem('isLoggedIn');

    // navigate to the home route
    history.replace('/home');
  }

  isAuthenticated() {
    // Check whether the current time is past the
    // access token's expiry time
    let expiresAt = this.expiresAt;
    return new Date().getTime() < expiresAt;
  }
}

アクセストークンやIDトークンの取り出しや期限の計算、ローカルストレージへの書き込みなどをコピペする必要があり、面倒な面がありました。また実装後にサンプルコードにアップデートがあった場合、追従した方が良いのかどうか考える必要もありました。

auth0-spa-js には上記の処理が含まれており、ログインやログアウト、トークンの取得などがAPIで使えるようになります。シングルアプリケーションへのAuth0の組み込みが非常にシンプルになります。

インストール方法

CDNまたはNPM(Yarn)でインストール可能です。

CDN

<script src="https://cdn.auth0.com/js/auth0-spa-js/1.0.1/auth0-spa-js.production.js"></script>

NPM

$ npm install @auth0/auth0-spa-js

Yarn

$ yarn add @auth0/auth0-spa-js

各APIの使い方

Getting Started の内容を見ていきましょう。かなり簡単に認証周りの処理が書けることがお分りいただけると思います。

クライアントの生成

const auth0 = await createAuth0Client({
  domain: '<AUTH0_DOMAIN>',
  client_id: '<AUTH0_CLIENT_ID>'
});

ログイン

await auth0.loginWithPopup();
//logged in. you can get the user profile like this:
const user = await auth0.getUser();
console.log(user);

アクセストークン取得(API呼び出し)

const accessToken = await auth0.getTokenSilently();
const result = await fetch('https://myapi.com', {
    method: 'GET',
    headers: {
      Authorization: `Bearer ${accessToken}`
    }
  });
const data = await result.json();
console.log(data);

ログアウト

auth0.logout();

新しいサンプルプロジェクトを使おう

Auth0が提供しているシングルページアプリケーション用のサンプルもつい4日前ほどに更新されています。現時点ではAngular、React、Plain(Vanilla)が対応済みです。

近々Vueも(きっと)置き換わることでしょう。ウォッチしておくと良いと思います。

すでに組み込み済みの方は サンプルコードのままで事足りている場合は入れ替えることを推奨します。 ぜひ検討してみてください!