今回達成すること
今回は、Railsから返されるログイン成功時のレスポンスを、フロントに保存する実装を行います。
レスポンスJSONの保存先
Railsから返されるレスポンスJSONの保存先は、
user
=> Vuexに、exp
(有効期限) => ローカルストレージに
保存します。
認証クラスの作成
認証関連を一手に請け負うAuthentication
クラスを新たに作成し、その中で今回の実装を行います。
認証を扱うプラグインを作成する
まずは、Nuxt.jsの「plugins」ディレクトリに
root $ touch front/plugins/auth.js
作成したプラグインの読み込み設定を、
最初に処理を行うため、plugins
の一番上に追加してください。
front/nuxt.config.js
export default {
...
plugins: [
// 1番上に追加
'plugins/auth',
'plugins/axios',
'plugins/myInject'
],
...
}
Authenticationクラスを作成する
作成したAuthentication
クラスを宣言します。
このクラスは、
- 有効期限の保存
- ログインフラグ
- ログイン業務
- ログアウト業務
の認証関連業務を一手に請け負います。
front/plugins/auth.js
class Authentication {
constructor (ctx) {
this.store = ctx.store
this.$axios = ctx.$axios
}
}
export default ({ store, $axios }, inject) => {
inject('auth', new Authentication({ store, $axios }))
}
-
inject(<呼び出し名>, クラスの初期化)
...inject
することにより、クラス内のメソッドをthis.$auth
で呼び出すことができます。 -
{ store, $axios }
... Nuxt.jsのcontextを取得し、constructor
内で代入しています。これにより、クラス内で
Vuex
と$axios
が扱えるようになります。
ストレージに有効期限を保存するメソッド
Railsから返ってきた有効期限をローカルストレージに保存する、setStorage
を追加します。
front/plugins/auth.js
// 追加
const storage = window.localStorage
const keys = { exp: 'exp' }
class Authentication {
constructor (ctx) {
...
}
// 追加
// storageに保存
setStorage (exp) {
storage.setItem(keys.exp, exp * 1000)
}
}
...
-
setItem(<キー>, 値)
... ローカルストレージに保存する。キーには
'exp'
が入ります。値には、有効期限を1000ミリ秒に変換して保存しています。
これは、JavaScriptの
getTime()
が1000ミリ秒を返すためです。
ストレージを削除するメソッド
ローカルストレージを削除するremoveStorage
を追加します。
front/plugins/auth.js
...
class Authentication {
...
setStorage (exp) {
storage.setItem(keys.exp, exp * 1000)
}
// 追加
// storageを削除
removeStorage () {
for (const key of Object.values(keys)) {
storage.removeItem(key)
}
}
}
...
removeItem(<キー>)
... 引数のキーと一致するローカルストレージの値を削除する。
有効期限を取得する
ローカルストレージから有効期限を取得するgetExpire
を作成します。
front/plugins/auth.js
...
class Authentication {
...
removeStorage () {
for (const key of Object.values(keys)) {
storage.removeItem(key)
}
}
// 追加
// storageの有効期限を複合して返す
getExpire () {
return storage.getItem(keys.exp)
}
}
有効期限内であるかを判定するメソッド
現時刻と有効期限を比較して、
- 期限内である場合
true
、 - 期限外の場合
false
を返す
isAuthenticated
を追加します。
front/plugins/auth.js
...
class Authentication {
...
removeStorage () {
for (const key of Object.values(keys)) {
storage.removeItem(key)
}
}
// 追加
// 有効期限内の場合はtrueを返す
isAuthenticated () {
return new Date().getTime() < this.getExpire()
}
}
...
-
getTime()
... 1970年1月1日午前0時0分0秒からの経過秒数を1000ミリ秒(1秒 == 1000)で返す。この経過秒数の事をUNIXTIME(ユニックスタイム)と言い、タイムゾーンはUTC(世界標準時)が使用されます。
一方、Railsから返ってきた
exp
の値も、UNIXTIMEを使用するため、正しい比較が行われます。
ログイン業務を行うメソッド
ログイン時は、
- 有効期限をローカルストレージに保存し
- ユーザーをVuexに保存します。
front/plugins/auth.js
...
class Authentication {
...
isAuthenticated () {
return new Date().getTime() < storage.getItem(keys.exp)
}
// 追加
// ログイン業務
login ({ exp, user }) {
this.setStorage(exp)
this.store.dispatch('getCurrentUser', user)
}
}
...
ログアウト業務を行うメソッド
ログアウト時は、
- アクセストークンの削除
- ローカルストレージを削除
- Vuexのユーザーを
null
にします。
front/plugins/auth.js
...
class Authentication {
...
login ({ exp, user }) {
...
}
// 追加
// ログアウト業務
logout () {
this.$axios.$delete('/api/v1/user_token')
this.removeStorage()
this.store.dispatch('getCurrentUser', null)
}
}
...
Vuexにユーザーを保存する
Railsから返ってきたユーザーをVuexに保存する実装を行います。
- ストア
- アクション
- ミューテーション
を追加します。
front/store/index.js
export const state = () => ({
...
current: {
// user追加
user: null,
project: null
},
...
})
export const getters = {}
export const mutations = {
...
setCurrentProject (state, payload) {
state.current.project = payload
},
// 追加
setCurrentUser (state, payload) {
state.current.user = payload
}
}
export const actions = {
...
getCurrentProject ({ state, commit }, params) {
...
},
// 追加
// 現在のユーザーを設定する
getCurrentUser ({ commit }, user) {
commit('setCurrentUser', user)
}
}
ログインメソッドを追加する
ここまでに、
- 有効期限をローカルストレージに保存、
- ユーザーをVuexに保存
- それらを実行する
login
メソッド
を作成しました。
このlogin
メソッドを
確認の為、Vuexのユーザーをコンソールで出力してみましょう。
front/pages/login.vue
...
export default {
...
methods: {
async login () {
...
},
// ログイン成功
// async 追記
async authSuccessful (response) {
// 変更
await this.$auth.login(response)
console.log(this.$store.state.current.user)
// 削除
// console.log(response)
},
...
}
}
ログインを実行する
コンテナを起動して、http://localhost:8080/login にアクセスしましょう。
メールとパスワードを打ち込んで、ログインしてください。
コンソールを確認する
Vuex内のユーザーが保存されているか確認します。
ローカルストレージを確認する
ローカルストレージに有効期限が保存されているか確認します。
「Application」タブ => 「Storage」=>「Local Storage」を見てください。
Key
に「exp」、Value
に「1000ミリ秒に変換した有効期限」が保存されていれば成功です。
コンソールを削除する
front/pages/login.vue
...
<script>
export default {
...
// ログイン成功
async authSuccessful (response) {
await this.$auth.login(response)
// console.log(this.$store.state.current.user) 削除
},
...
}
}
</script>
ローカルストレージを削除する
ローカルストレージのexp
にカーソルを合わせ「deleteキー」で値を削除してください。
コミットする
今回の作業は以上です。
「front」ディレクトリ内でコミットしておきましょう。
root $ cd front
front $ git add -A && git commit -m "add_plugins_auth.js" && cd ..
root $
まとめと予告
今回は、Nuxt.jsにログイン成功後に返ってくるレスポンスを保存する実装を行いました。
これでNuxt.js側でログインユーザーが扱えるようになりましたね。
ただ、ローカルストレージに保存した有効期限は、誰でも簡単に改ざんできる状態です。
そこで、次回はこの有効期限を暗号化処理を行います。
それでは!