76
70

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GMOペパボAdvent Calendar 2017

Day 6

Nuxt.jsでlocalStorageを用いる際のTipsとハマったこと

Last updated at Posted at 2017-12-05

GMOペパボ、ロリポップのエンジニア@sunecosuriです。
昨日は@bake0937による、Macの開発環境をzshで良い感じにするでした。
ghq + peco の組み合わせ、一度知ったら手放せないくらい便利ですよね。

さて、今回私はNuxt.jsでのlocalStorageを扱う際にハマったお話とTipsのようなものをご紹介したいと思います。

Nuxt.js について

Nuxt.jsはSSR基盤を持ったVue.jsを用いたwebpackベースのフレームワークです。
詳細は公式ページを御覧ください。

Nuxt.jsの認証について

Nuxt.jsで認証を行うにあたって、nuxtServerInitという
アプリケーションがロードされたとき、サーバーから取得できるデータをVuexのstoreに渡すことができる機構が提供されています。
session認証になりますが、公式にも以下のようにサンプルコードが提供されています。
sessionをそのままstateに渡すといった内容になります。

// store/index.js
export const actions = {
  nuxtServerInit ({ commit }, { req }) {
    if (req.session && req.session.authUser) {
      commit('SET_USER', req.session.authUser)
    }
  }
}

これを用いて以下のようにlocalStorageからTokenを取得して認証を行おうとすると、初回ロード時にトークンが与えられていないというエラーが出て処理が失敗してしまいます。

//localStorageからtokenを取得できない
export const actions = {
  nuxtServerInit ({ commit, state, dispatch }, { req }) {
    if (localStorage.accessToken) {
      commit('user/setToken', localStorage.token)
    }
  }
}

原因はライフサイクルにありました。
nuxtServerInitはSSRする際に最初に処理を行うためブラウザにあるlocalStorageにそもそもアクセスできるはずがありません。

Nuxt.jsのライフサイクル

image.png

これは、nuxtClientInitといったプラグインを独自に定義することで取得することができます。
やっていることはactionを定義するいたってシンプルなものですがnuxt.config.js で定義しているssr: falseがポイントになります。

// nuxt.config.js
module.exports = {
  plugins: [{ src: '~/plugins/nuxt-client-init.js', ssr: false }]
}
// plugins/nuxt-client-init.js
export default async (ctx) => {
  await ctx.store.dispatch('nuxtClientInit', ctx)
}

これを用いることでほぼ同じ記述でtokenを取得することができるようになります。

// localStorageからtokenを取得できる
export const actions = {
  nuxtClientInit ({ commit, state, dispatch }, { req }) {
    if (localStorage.accessToken) {
      commit('user/setToken', localStorage.token)
    }
  }
}

Token認証を扱うにあたって

取得したトークンを認証ヘッダに加えてリクエストを送る際に個人的にハマったポイントがありました。

それは、Client側でトークンを取得しているため、Vue.jsのライフサイクルにおいてbeforeMount以降でないと処理ができないという点です。

所感としては、localStorageから値を表示するだけであれば上記は適していますが、「SSR × SPA」を行っているNuxt.jsにおいてはlocalStorageの値を基にAjaxでリクエストを送り、レスポンスを基に処理を行うといったシーンにおいては機能こそするものの、ページ遷移ごとにカクつきが生じて高速なページ遷移といったSPAとしてのメリットが失われてしまう、複雑な処理になるほどより管理しにくい構造になってしまうといった印象を持ちました。

まとめ

  • Nuxt.jsでlocalStorageを用いた認証を行うには上記のライフサイクルを意識する必要がある。
  • そもそもSSRする必要があるのかというのを再考する。
    認証の結果に応じて表示するなど、場合によってはtemplateブロックにやssr:falseオプションなどを使えば解決できる問題かもしれません。

明日は@gatchan によるVue.jsでモーダルウインドウをつくったことについてのお話です。
-> GMOペパボ Advent Calendar 2017

76
70
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
76
70

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?