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
に設定を追加します。
modules: [
'@nuxtjs/auth'
],
Auth Moduleの設定を行う
nuxt.config.js
にAuth Moduleの設定を追加しましょう。
設定の詳細な内容はこちらのドキュメントを確認してください。
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/login
と api/me
が叩かれ、ヘッダーに付与するtokenとuser情報がstoreに保存されます。
その後、 ログイン後のページにリダイレクトされます。
store.$auth.loggedIn
でログインしているか否かを確認できるので、 middlewareにログイン判定を実装して、ログイン済みならログイン後のページへリダイレクトするようにしています。
また、 store.$auth.getToken('local');
でヘッダーに付与するtokenが取得できるため、axiosの共通設定部分に指定して使用することもできます。
参考: Nuxt.jsでaxiosの共通処理を作成し、API呼び出し処理をラップして使用する
<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>
ちなみに、nuxt.config.js
に設定したログイン後のリダイレクト先をhome: false
にすることで、ログイン後のリダイレクトのタイミングを任意に制御できます。
<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情報を取得することもできます。
<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>
以上で実装完了です。
簡単にログイン/ログアウト処理が実装できるので、とてもオススメです!