Vue.js でログイン機能を実装する

プログラミング
この記事は約8分で読めます。
スポンサーリンク

前提

この記事は @vue/cli を使用した内容となっております。

バージョン

"vue": "^2.5.17",
"vue-router": "^3.0.1",
"vuex": "^3.0.1"

ページ構成

  • ホーム
  • プロフィール
  • ログイン

このうち、プロフィールはログイン認証が必要なページとします。

ソースファイル

上記ページ構成のファイルをそれぞれ用意します。

  • src/views/Home.vue
  • src/views/Profile.vue
  • src/views/Login.vue

※上 2 つの中身は適当で大丈夫です。ログインページは後述します。

ルーター設定

src/router.js を編集します。

import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import store from './store' // (1)

Vue.use(Router)

const router = new Router({
  routes: [
    {
      path: '/',
      component: Home
    },
    {
      path: '/profile',
      component: () => import('./views/Profile.vue'),
      meta: { requiresAuth: true } // (2)
    },
    {
      path: '/login',
      component: () => import('./views/Login.vue')
    }
  ]
})

// (3)
router.beforeEach((to, from, next) => {
  if (to.matched.some((record) => record.meta.requiresAuth)) {
    if (!store.getters.loggedIn) {
      next({
        path: '/login',
        query: {
          redirect: to.fullPath,
          message: true
        }
      })
    } else {
      next()
    }
  } else {
    next()
  }
})

export default router

(1) ログイン情報を参照するため store をインポートしておきます。

(2) プロフィールページはログイン認証が必要なため、 meta: { requiresAuth: true } を追加しておきます。

ここでの requiresAuth は適宜変更して大丈夫です。

(3) ページ遷移した際に、ログインしていない状態かつログイン認証が必要な場合は、ログインページに遷移するようにしています。

ログインページに遷移させる際、redirect: to.fullPath を与えて、ログイン完了後にもともと遷移しようとしていたページにリダイレクトできるようにしております。

message: true に関しては、強制的にログインページに飛ばされた時用にメッセージを表示させるフラグになります。

ストア設定

src/store.js を編集します。

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    userId: ''
  },
  getters: {
    loggedIn: (state) => {
      return Boolean(state.userId.trim())
    }
  },
  mutations: {
    setUserId(state, userId) {
      state.userId = userId
    }
  },
  actions: {}
})

ログインした際のユーザ ID を保持しておくようにしています。

getters の loggedIn では、userId に何らかの値がセットされている場合に true を返すようにしています。

ルートページの設定

src/App.vue を編集します。

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/profile">Profile</router-link> |
      <a @click="logout()" v-if="$store.getters.loggedIn">Logout</a>
      <!-- (1) -->
      <router-link
        :to="'/login?redirect=' + $route.fullPath"
        v-else-if="$route.path !== '/login'"
       >Login</router-link
      >
      <!-- (2) -->
    </div>
    <div v-if="$route.query.message">ログイン認証が必要なページです。</div>
    <!-- (3) -->
    <router-view />
  </div>
</template>

(1) ログアウト処理をするためのリンクです。

ログインしている状態の時にだけ表示するようにしています。

(2) ログインページに遷移するためのリンクです。

遷移先のパラメータに redirect を含めることで、ログイン処理後に元いたページにリダイレクトさせることができるようになります。

また、ログインしていない状態かつログインページ以外で表示するようにしています。

(3) 強制的にログインページに飛ばされた際に表示させるメッセージです。

<script>
export default {
  methods: {
    logout () {
      this.$store.commit('setUserId', '')
      if (this.$route.meta.requiresAuth) {
        this.$router.push({
          path: '/login',
          query: { redirect: this.$route.fullPath }
        })
      }
    }
  }
}
</script>

ストアで保持しているユーザ ID を空にします。

また、ログインが必要なページでログアウトした際、強制的にログインページに飛ばすようにしています。

この時もやはりリダイレクトで戻って来られるようにパラメータを渡しています。

ログインページの設定

src/views/Login.vue を編集します。

<template>
  <div class="about">
    <h1>This is an login page</h1>
    <input v-model="userId" />
    <button @click="login()" :disabled="!userId">ログイン</button>
  </div>
</template>

ユーザ ID 入力欄とログインボタンを設置しています。

ログインボタンは、ユーザ ID が未入力の場合は非活性にしています。

<script>
export default {
  data () {
    return {
      userId: ''
    }
  },
  methods: {
    login () {
      this.$store.commit('setUserId', this.userId) // (1)
      this.$router.push(this.$route.query.redirect) // (2)
    }
  }
}
</script>

(1) 入力したユーザ ID でストアを更新しています。

(2) 元いたページにリダイレクトさせます。

参考

ルートメタフィールド | Vue Router
Vue.js の公式ルータ

コメント

タイトルとURLをコピーしました