LoginSignup
212
177

More than 3 years have passed since last update.

Nuxt.jsでAuth Moduleを使ってログイン機能を実装する

Last updated at Posted at 2019-10-13

Nuxt.jsを使ったプロジェクトで、Auth Moduleを使ってJWT認証を実装したので、忘れないうちにまとめておきます。

ざっくり流れを説明すると、

  • クライアント側からサーバー側へメールアドレスとパスワードを送信する
  • サーバー側はトークンを返す

というシンプルなものです。
サーバーが返したトークンは、クライアント側がAPIを叩く際にヘッダーに付与して使用します。

ログイン時のリクエストとレスポンス

クライアント側は api/login に下記のbodyを持ったPOSTリクエストを送信するものとします。

{
  "email": "example@example.xom",
  "password": "password"
}

サーバー側はレスポンスとして、ヘッダーに付与するためのトークンを返します。

{
  "token": "xxxxxxxxxxxxxx"
}

ユーザー情報を返すAPIを用意する

ヘッダーに Authorization: Bearer xxxxxxxxxxxxxx を付与して api/me にGETリクエストを送ることにより、下記のようなユーザー情報を返すAPIを用意します(内容は一例です)。

{
  "id": 1,
  "name": "tanaka hiroshi",
  "age": "32"
}

Auth Moduleを導入する

Auth Moduleを導入します。

npm install --save @nuxtjs/auth

Auth Moduleはvuex storeを使用するため、storeを使用していない場合は store/index.js という空のファイルを作成しましょう。

そして nuxt.config.js に設定を追加します。

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

Auth Moduleの設定を行う

nuxt.config.js にAuth Moduleの設定を追加しましょう。
設定の詳細な内容はこちらのドキュメントを確認してください。

nuxt.config.js
export default {
  auth: {
    redirect: {
      login: '/login',   // 未ログイン時に認証ルートへアクセスした際のリダイレクトURL
      logout: '/login',  // ログアウト時のリダイレクトURL
      callback: false,   // Oauth認証等で必要となる コールバックルート
      home: '/',         // ログイン後のリダイレクトURL
    },
    strategies: {
      local: {
        endpoints: {
          login: { url: 'api/login', method: 'post', propertyName: 'token' },
          user: { url: 'api/me', method: 'get', propertyName: false},
          logout: false
        },
      }
    }
  },
}

以上で設定完了です!

ログイン機能の作成

サンプルとして、下記のようなログインページを実装します。

login関数の this.$auth.loginWith('local', { data: this.form }); の部分でログインを実行します。
これを実行すると、 先程 nuxt.config.js で設定した api/loginapi/me が叩かれ、ヘッダーに付与するtokenとuser情報がstoreに保存されます。
その後、 ログイン後のページにリダイレクトされます。

store.$auth.loggedIn でログインしているか否かを確認できるので、 middlewareにログイン判定を実装して、ログイン済みならログイン後のページへリダイレクトするようにしています。

また、 store.$auth.getToken('local'); でヘッダーに付与するtokenが取得できるため、axiosの共通設定部分に指定して使用することもできます。
参考: Nuxt.jsでaxiosの共通処理を作成し、API呼び出し処理をラップして使用する

pages/login.vue
<template lang="pug">
.login-container
  el-form(:model="form")
    el-form-item(label="メールアドレス")
      el-input(v-model="form.email")
    el-form-item(label="パスワード")
      el-input(v-model="form.password" type="password")
    el-button(type="primary" @click="login") ログイン
</template>

<script>
export default {
  middleware({ store, redirect }) {
    if(store.$auth.loggedIn) {
      redirect('/');
    }
  },
  data() {
    return {
      form: {
        email: '',
        password: ''
      }
    }
  },
  methods: {
    async login() {
      try {
        const response = await this.$auth.loginWith('local', { data: this.form });
        console.log(response);
      } catch(error) {
        console.log(error);
      }
    }
  }
}
</script>

<style lang="scss">
.login-container {
  margin: 50px auto;
  width: 300px;
  text-align: center;
}
</style>

スクリーンショット 2019-10-13 12.54.48.png

ちなみに、nuxt.config.jsに設定したログイン後のリダイレクト先をhome: falseにすることで、ログイン後のリダイレクトのタイミングを任意に制御できます。

pages/login.vue
<script>
methods: {
  async login() {
    try {
      const response = await this.$auth.loginWith('local', { data: this.form });
      console.log(response);

      // ここでホームへリダイレクトする前に行いたい処理

      this.$router.replace({ path: '/' }); // 任意のタイミングでリダイレクト
    } catch(error) {
      console.log(error);
    }
  }
}
</script>

ログアウト機能の作成

サンプルとして、下記のようなログイン済みページを実装します。

logout関数の this.$auth.logout(); の部分でログアウトを実行します。
これを実行すると、storeに保存されたuser情報が破棄され、ログインページにリダイレクトされます。

ログインページと同様に store.$auth.loggedIn でログインしているか否かを確認して、 middlewareにログイン判定を実装しています。
ログインしていなかったらログインページへリダイレクトするようにしています。

また、 this.$auth.user でuser情報を取得することもできます。

index.vue
<template lang="pug">
.container
  p 名前:{{ user.name }}
  p 年齢:{{ user.age }} 歳
  el-button.button(type="primary" @click="logout") ログアウト
</template>

<script>
export default {
  middleware({ store, redirect }) {
    if(!store.$auth.loggedIn) {
      redirect('/login');
    }
  },
  computed: {
    user() {
      return this.$auth.user;
    }
  },
  methods: {
    logout() {
      this.$auth.logout();
    },
  }
}
</script>

<style lang="scss">
.container {
  margin: 50px auto;
  width: 300px;
  text-align: center;

  .button {
    margin-top: 30px;
  }
}
</style>

スクリーンショット 2019-10-13 13.06.59.png

以上で実装完了です。
簡単にログイン/ログアウト処理が実装できるので、とてもオススメです!

212
177
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
212
177