LoginSignup
17
17

More than 3 years have passed since last update.

Nuxt.jsと認証 ~tokenの扱い~

Last updated at Posted at 2019-09-18

最初はaxiosで取得したtokenをstateで持たせてページ遷移の際に毎回APIを叩く処理を考えたのですが
stateはページ遷移の際消えるので考えていた処理ができませんでした。

調べてみると王道の手法はtokenをセッションブラウザのクッキーに保存しページ遷移時にstateに変更を加えるという方法でした。

クッキーを処理するために下記moduleを入れます。

npm install js-cookie --save
npm install cookieparser --save

続いてstoreの処理

store/index.js
const cookieparser = require('cookieparser')


export const state = () => ({
  auth: false,
})

//mutationsはstateに反映する処理を書く
//発火させるのはまた別の箇所で記述
export const mutations = {
  setAuth(state, auth) {
      state.auth = auth
  },
}


export const actions = {
  nuxtServerInit({commit}, {req}) {
    let auth = null
    if (req.headers.cookie) {
      const parsed = cookieparser.parse(req.headers.cookie)
      try {
        auth = JSON.parse(parsed.auth)
      } catch (err) {
        // 有効なクッキーが見つからない場合
      }
    }
    commit('setAuth', auth)
    //↑ここで発火(stateに反映させてる)
  }

View側の処理

pages/login.vue
<template>
  <main>
    <div id="registrationForm" class="form-wrapper">
      <form>
        <div class="form-item">
          <label>メール</label>
          <input v-model="username" type="email" name="email"></input>
        </div>
        <div class="form-item">
          <label>パスワード</label>
          <input v-model="password" type="password" name="password" ></input>
        </div>
        <div class="button-panel">
          <button class="button" title="ログイン" v-on:click="Login" type="button" value="ログイン">ログイン</button>
        </div>
      </form>
    </div>
  </main>
</template>


<script>
  const Cookie = require('js-cookie')
  export default {
    middleware: 'notAuthenticated',
    data() {
      return {
        username: "",
        password: "",
        token: ""
      };
    },
    created() {
    },
    methods: {
      async Login() {
        setTimeout(() => {
          const postData = {
            scope: "*",
            grant_type: "password",
            client_id: "5",
            client_secret: process.env.CLIENTSECRET,
            username: this.username,
            password: this.password
          };
          this.$axios.post(process.env.AUTH, postData).then((res) => {
            const auth = res.data
            this.$store.commit("setAuth", {auth});
            //↑ここでstate変更
            Cookie.set('auth', auth)
            //↑ここでCookieにtoken保存
            this.$router.push("/admin");
          })
        }, 1000)
      }
    }
  };
</script>

nuxtServerInit アクション

公式から引用

nuxtServerInit というアクションがストア内に定義されているときは、Nuxt.js はそれをコンテキストとともに呼び出します(ただしサーバーサイドに限ります)。サーバーサイドからクライアントサイドに直接渡したいデータがあるときに便利です。

つまりnuxtServerInit関数を使用すれば、アプリケーションがロードされた際にセッションブラウザのクッキーをVuexのstoreに渡すことができます。

この方法であれば認証かけたいページで毎回APIを立たなくても
Middleware等で下記処理を書けばよい

export default function ({ store, redirect }) {
  // ユーザが認証されて場合
  if (store.state.auth) {
    return redirect('/admin')
  }
}
export default function ({ store, redirect }) {
  // ユーザが認証されていない場合
  if (!store.state.auth) {
    return redirect('/login')
  }
}

参考記事

17
17
0

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
17
17