Nuxt.jsのmiddlewareとAuth Moduleを使ってAuth0ログインを実装する

Published: 2021年1月15日 by tomsato

今回の記事について

Vue.js / Nuxt.jsにおけるログインの実装方法を調べることにしました

Nuxt.jsのAuth Moduleとmiddlewareを使うと実装できるということでやり方についてまとめつつ

サンプルも作成することで理解度をあげたいと思います

登場人物

Auth0について

Auth0とは

IDaaSを提供している認証基盤サービスのこと

IDaaSとは「Identity as a Service」の略であり、クラウド経由でログイン認証を管理することができる

Auth0を使うことで数行のコードを書くだけでアプリケーションにログイン認証を実装することができる

開発者向けのドキュメントは英語だが、アプリからフロント、バックエンドまで幅広い言語に対応しており、言語毎にドキュメントも作成されている

Choose your application type

nuxt auth01

ソーシャルログインを実装することもでき、連携できる数が多い

↓下記の画像は連携例、表示しきれないだけで実際はもっとある

nuxt auth02

また導入実績としては9000社以上あるとのことなので実績も多い

Twitter: Auth0 Japan

Multi-factor Authentication(多要素認証)にも対応しているためため、認証に関しては大抵のことができるはず

認証周りを全てAuth0に丸投げしてしまうということはAuth0がダウンするとサービスが使えなくなってしまうが、2021年1月22日現在JP-1は稼働率は99.999%以上となっているらしい、以下のページより確認できる

Auth0 Status Page

nuxt auth06

Auth0の料金体系について

当然のことながらOSSではないためお金がかかる

Pricing- Auth0

2021年1月現在は月額$23とのこと(Web検索して2019年の記事を見ると$13と書いてあったのでもしかしたら値上げしたのかも?)

認証処理はサービスロジックではないためあまり手間をかけたくない部分ではあるが、個人情報流出漏洩まで繋がってしまうと会社の信頼に関わってしまうため念密に考え実装する必要がある

会社によってはセキュリティ専門の人材がいるぐらい重要度が高いためそこをAuth0にやってもらえると考えた上で懐の事情と相談した上で採用するかどうかは考えるべきかも

22日間の無料トライアルがあり以下のことができる

  • 最大7000アクティブユーザー & ログイン回数無制限
  • パスワードレス認証
  • Web, iOS, Android対応
  • 2種類までのソーシャルログイン設定
  • Rules機能の利用は無制限

Sign Up - Auth0

Auth Moduleとは

Nuxt.jsアプリケーションに簡単に認証を追加することができる公式モジュールのこと

Introduction - nuxt auth docs

下記サンプルの実装を見ながらどんなものかを理解してもらえればと

middlewareについて

ページがレンダリングされる前(SSR処理などが行われる前)に設定された関数を実行することができる

Middleware プロパティ - NuxtJS

従って主に認証しているかのチェックに使われることが多い

middlewareの実行順序について覚えておくとどのタミングで認証チェックしているかがわかるのでメモ程度に記載しておくことにする

SSRあり

  1. plugins (SSR)
  2. middleware (SSR)
  3. fetch (SSR)
  4. beforeCreate (SSR)
  5. plugins (CSR)
  6. beforeEach (CSR)
  7. afterEach (CSR)
  8. beforeCreate (CSR)

SSRなし

  1. beforeEach (CSR)
  2. middleware (CSR)
  3. fetch (CSR)
  4. afterEach (CSR)
  5. beforeCreate (CSR)

作成するサンプルアプリケーションについて

構成

以下の3つのページ構成のサンプルアプリケーションを作成する

  • トップページ:見出しや文言を表示するだけのページ
  • ログイン画面:ログインをすることができるページ
  • マイページ:ログイン時のみ表示できるページ、Auth0で登録している名前を表示される

サンプルはこちらのGitHubリポジトリに用意しています、使い方はREADME.mdをご覧頂けたらと

https://github.com/tomsato/sample-nuxt-auth

トップページ

nuxt auth ui 1

ログイン画面

nuxt auth ui 2

「Auth0でログイン」のボタンを押すとログインモーダルが表示される

nuxt auth ui 3

ログインをするとマイページにリダイレクトされる

マイページ

ログインしていない状態でアクセスするとアラートモーダルを出しつつログインページにリダイレクトする

nuxt auth ui 4

ログインしていればニックネームが表示される

nuxt auth ui 5

※ 軽微なバグとして非ログイン時にナビゲーションバーにある「MyPage」へのリンク経由でマイページを表示すると上記の挙動になるが、/mypageを直接表示するとアラートモーダルは表示されず「こんにちは、ゲストさん」という表示になる、この辺りは必要に応じて修正する必要がある

サンプルアプリケーションの作成 - 事前準備

Nuxt.jsの準備

まずばcreate-nuxt-appを使ってNuxt.jsのプロジェクトを用意する

// とりあえずUniversalにはした方が良いかも
$ yarn create nuxt-app sample-nuxt-auth
create-nuxt-app v3.4.0
✨  Generating Nuxt.js project in sample-nuxt-auth
? Project name: sample-nuxt-auth
? Programming language: TypeScript
? Package manager: Yarn
? UI framework: Bulma
? Nuxt.js modules: Axios
? Linting tools: ESLint, Prettier, Lint staged files, StyleLint
? Testing framework: Jest
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Server (Node.js hosting)
? Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript)
? Continuous integration: None
? Version control system: Git
...
  See : https://typescript.nuxtjs.org/cookbook/components/
✨  Done in 312.43s.

$ cd sample-nuxt-auth/
$ yarn dev

この状態で以下にアクセスするとサンプルページを見ることができる

http://localhost:3000/

nuxt auth03

Auth Moduleの追加

パッケージ追加

$ yarn add @nuxtjs/auth
// TypeScriptを使う際には型定義も導入する
$ yarn add -D @types/nuxtjs__auth

設定の追加

// nuxt.config.js

  modules: [
    ...
    '@nuxtjs/auth', // 追加
  ]
// nuxt.config.js

  auth: {
    strategies: {
      auth0: {
        domain: 'XXXXX', // Auth0 App Domain
        client_id: 'XXXXX', // Auth0 App Client ID
      },
    },
    redirect: {
      login: '/',  // 未ログイン時のリダイレクト先
      logout: '/logout',  // ログアウト処理を実行した直後のリダイレクト先
      callback: '/callback',  // コールバックURL
      home: '/mypage',  // ログイン後に遷移するページ
    },
  },

domainやclient_idはAuth0の画面内で確認することができる

ログイン後に表示されるページから「Applications」タブ →「Default App」をクリックすると以下のような表示になるはずで、その中の「Domain」と「Client ID」を記載することになる

nuxt auth04

// tsconfig.json

    "types": [
      ...
      "@types/nuxtjs__auth" // 追加
    ]

また store/index.js を空で用意する、ない場合は以下のエラーが出る

FATAL  Enable vuex store by creating store/index.js.

$auth についてIDE等でESLintのエラーが出た場合は以下のファイルを作成しておく

// vue-shim.d.ts

import { Auth } from 'nuxtjs__auth'

declare module 'vue/types/vue' {
  interface Vue {
    $auth: Auth
  }
}

Auth0の設定方法

「Allowed Callback URLs」の設定

Callback URLを登録する、これを設定しないとうまく動作しないため必ず実施する

Auth0でログイン後に「Applications」タブより「Default App」をクリック、「Domain」や「Client ID」の表示の少し下の方に設定項目があるはず

今回は「http://localhost:3000/callback」を設定する

nuxt auth05

サンプルアプリケーションの作成 - 実装

画面の作り込みを行う

差分はGitHubのプルリクとしてもまとめたのでこっちの方がわかりやすいかも

Auth ModuleでAuth0ログイン認証を実装する

layouts/default.vue

全ページ共通のナビゲーションバーの実装

CSSフレームワークとしてはBulmaを使っているのでそれにあった書き方にしている

<template>
  <div>
    <nav class="navbar is-light">
      <div class="navbar-brand">
        <nuxt-link to="/" class="navbar-item">Home</nuxt-link>
        <nuxt-link to="/mypage" class="navbar-item">MyPage</nuxt-link>
        <nuxt-link to="/login" class="navbar-item">Login</nuxt-link>
      </div>
    </nav>
    <Nuxt />
  </div>
</template>

pages/callback.vue

ログイン後にID Providerによってこのパスにリダイレクトされる

nuxt.config.jsでhomeの設定にてログイン後には/mypageにリダイレクトするようになっているため、ログイン時にはこのページが一瞬見えてすぐに/mypageにリダイレクトするように見える

<template>
  <div class="container has-text-centered mt-6">
    <div>
      <h1 class="title">sample-nuxt-auth</h1>
      <h2 class="subtitle">Callback</h2>
      <p>Please Wating...</p>
    </div>
  </div>
</template>

pages/index.vue

<template>
  <div class="container has-text-centered mt-6">
    <div>
      <h1 class="title">sample-nuxt-auth</h1>
      <h2 class="subtitle">トップページ</h2>
      <p>このサイトはNuxt.jsでAuth0を試すサンプルアプリケーションです</p>
    </div>
  </div>
</template>

pages/login.vue

ログイン画面の実装

ログインボタンをクリックするとthis.$auth.loginWith('auth0')が呼ばれログインモーダルが立ち上がる

<template>
  <div class="container has-text-centered mt-6">
    <div>
      <h1 class="title">sample-nuxt-auth</h1>
      <h2 class="subtitle">ログインページ</h2>
      <button class="button is-dark is-large" @click="loginWithAuthZero">
        Auth0でログイン
      </button>
    </div>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  methods: {
    loginWithAuthZero() {
      this.$auth.loginWith('auth0')
    },
  },
})
</script>

pages/logout.vue

ログアウト後に呼ばれるページ

<template>
  <div class="container has-text-centered mt-6">
    <div>
      <h1 class="title">sample-nuxt-auth</h1>
      <h2 class="subtitle">ログアウトしました</h2>
    </div>
  </div>
</template>

※ 追記: ログアウトボタンを設置するのを忘れてしまいましたmm ログアウトボタンを用意してクリック時に this.$auth.logout() を実行するとログアウトされて /logout にリダイレクトされるはずです

pages/mypage.vue

ログインしていないと見ることができないマイページ

middleware: 'userAuth'にてページを表示する前にログインをしているかの認証部分の処理を呼び出している

なので認証をかけたいページについてmiddlewareの記述をすれば良い

<template>
  <div class="container has-text-centered mt-6">
    <div>
      <h1 class="title">sample-nuxt-auth</h1>
      <h2 class="subtitle">マイページ</h2>
      <p>こんにちは、さん</p>
    </div>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
  middleware: 'userAuth',
  computed: {
    famlyName() {
      return this.$auth.loggedIn ? this.$auth.$state.user.nickname : 'ゲスト'
    },
  },
})
</script>

middleware/userAuth.js

ログインしていない場合にalertモーダルを出しつつリダイレクトする処理を追加

export default function ({ store, redirect }) {
  if (!store.state.auth.loggedIn && process.client) {
    window.alert('ログイン画面を表示します')
    redirect('/login')
  }
}

動作確認

ここまで実装した上で yarn dev で起動してページにアクセスするとログイン画面ではログインができるように、マイページではログインしていなければログイン画面にリダイレクトをして、ログインしていれば名前を表示できるようになっているはず

もし実装漏れなど何かあればコメントいただけたらと思いますmm

終わりに

今回はVue.js / Nuxt.jsにおけるログインの実装例として

Auth0と、Nuxt.jsのAuth Moduleとmiddlewareを使った実装例を紹介しました

middlewareをうまく使えばチェック処理などができることがわかったかと思います

またAuth Moduleもnuxt.config.jsをちょろっといじるぐらいで認証を取り入れることができるため簡単さを感じていただけたかと思います

機会があればAuth0を使ったソーシャルログイン方法についてもまとめてみたいと思います

Vue

コメントを書く

※ 個別に返信が必要な時のみご記入ください

※ Emailは公開されません

※ 承認されると名前・コメントが下記に表示されます

コメント一覧

最近の投稿

ビジュアルリグレッションテストについてまとめ、ネットで調べると数多くのライブラリがありどれがどんな立ち位置なのか全体像がわかりずらかったのでどんな種類があるのか入門の入門としてまとめます、またPlaywrightを使って実際に触ってみました

社内ツールなどの超小規模なAPIをGolangで実装する際にフレームワークを使うべきかを、実際にnet/httpを使った実装とフレームワークを使った実装を比較することでどれだけ優位性があるかを見ていきたいと思います。今回はフレームワークにはシンプルで使いやすそうなEchoを使うことにします。

vue-pdfを使ってNuxt.jsで作成しているアプリケーションに pdfスライドを表示させるサンプルを作成しました README.md通りに実装してもうまくいかないところがあったのでそのあたり含めてまとめます

Vue.js / Nuxt.jsにおけるログインの実装方法をまとめる Auth0やNuxt.jsのAuth Moduleとmiddlewareについて調べつつサンプルを作成することで理解を深める

コンポーネント設計について考える Atomic DesignやPresentational Component, Container Componentについてまとめつつ 自分だったらVue.js / Nuxt.jsでどういうコンポーネント設計にするかについてまとめます

カテゴリ一覧

タグ一覧