Nuxt.jsでFirebase REST APIを使ったサインアップ・ログイン機能の作り方
Nuxt.jsでFirebase REST APIを使ったサインアップ・ログイン機能の作り方を紹介します。
Nuxt.jsでFirebase REST APIを使ったサインアップ機能の作り方
Firebase Authenticationを使用
まだサービスを使ったことがない人が、メールアドレスとパスワードで新規登録してサインアップできる機能を作ります。
Firebaseのプロジェクトを作成したら、Authenticationの「始める」をクリックします。
そして、サインアップの方法を選択します。
メールとパスワードであれば、上のように有効にして保存します。
Firebase認証REST APIのページでエンドポイントURLを取得
Firebase認証REST APIのページを訪れます。
そして、エンドポイントがリクエストを送る先なので、メール・パスワードでサインアップという項目を探して、そのエンドポイントに記載されているURLをコピーします。
https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=[API_KEY]
FirebaseのAPI_KEYを取得
この[API_KEY]の部分は、Firebaseで入手する必要があるので、プロジェクトの概要、アプリの追加でwebを選択してapikeyを取得します。
Firebaseの詳しい使い方に関しては、Nuxt.jsでfirebaseを使う方法を参考にしてみてください。
pages/auth/index.vueを作成
<template>
<div class="admin-auth-page">
<div class="auth-container">
<form @submit.prevent="onSubmit">
<AppInput type="email">Eメール</AppInput>
<AppInput type="password">パスワード</AppInput>
<AppButton type="submit">{{ isLogin ? 'ログイン' : 'サインアップ' }}</AppButton>
<AppButton
type="button"
btn-style="inverted"
style="margin-left: 10px"
@click="isLogin = !isLogin">{{ isLogin ? 'サインアップ' : 'ログイン' }}へ切り替える</AppButton>
</form>
</div>
</div>
</template>
formタグでは、@submitで即座にページ更新されると困るのでpreventをつけます。
axiosをグローバルに設定していないのなら、上のようにインポートします。
リクエストボディペイロードで、メールアドレス、パスワード、returnSecureTokenを設定する必要があると記載があるので、そのオブジェクトを用意します。
そのために、まずは、templateで、emailとpasswordにv-modelを追加します。
<AppInput type="email" v-model="email">Eメール</AppInput>
<AppInput type="password" v-model="password">パスワード</AppInput>
そしてdataに初期値を設定します。
data() {
return {
...
email: '',
password: ''
}
},
そして、オブジェクトを作成します。
{
email: this.email,
password: this.password,
returnSecureToken: true,
}
Nuxt.jsでFirebase REST APIを使ったサインイン・ログイン機能の作り方
すでに登録している人が、ログインできるようにする機能を作ります。
サインアップのときとほとんど同じですが、リクエストを送る先が変わります。
メール・パスワードでサインインという項目を探して、そのエンドポイントに記載されているURLをコピーします。
>>>サインイン(ログイン)の場合の公式サイト
https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=[API_KEY]
[API_KEY]の部分は、Firebaseで入手したものを使います。
リクエストボディペイロードの内容もログインとサインアップは同じです。
ログインとサインアップの処理をまとめる
ログインとサインアップの処理は同じで、URLのみが異なるので、次のようにscriptを書き換えます。
<script>
import axios from 'axios'
export default {
data() {
return {
isLogin: true,
email: '',
password: ''
}
},
methods: {
onSubmit() {
// デフォルトのURL(ログインとする)を設定
let authUrl = `https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=${process.env.firebaseAPIkey}`
// ログインモードでない場合、サインアップのURLをセット
if(!this.isLogin) {
authUrl = `https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=${process.env.firebaseAPIkey}`
}
// ログイン/サインアップの処理
axios.post(authUrl, {
email: this.email,
password: this.password,
returnSecureToken: true,
})
.then(result => {
console.log(result)
})
.catch(e => console.log(e))
}
}
}</script>
リクエストを送る先であるエンドポイントのURLを変数authUrlに格納して、isLoginで切り替えます。
その後、ログイン・サインアップの処理を記述します。
vuexでTokenを保持する
pages/auth/index.vue
処理内容はsctionsに移動するので、pages/auth/index.vueは、dispatchします。
methods: {
// ユーザー認証
onSubmit() {
this.$store.dispatch('authUser', {
isLogin: this.isLogin,
email: this.email,
password: this.password
})
// actionsでaxiosをreturnしているのでthen()が使える
.then(() => {
this.$router.push('/admin')
})
}
}
Firebaseのtokenを格納するためのstate、
それを保持できるようにするためのmutation、
authUserというactionをstore/index.jsに記述します。
store/index.js
state
state: {
token: null, //ユーザー認証
},
tokenを格納したいのでまずはstateに変数を用意します。
mutations
mutations: {
// ユーザー認証のmutation、tokenをセット
setToken(state, token) {
state.token = token
},
},
tokenをstateにセットするためにmutationを作成します。
actions
actions: {
// ユーザー認証のaction
authUser(vuexContext, authData) {
// デフォルトのURL(ログインとする)を設定
let authUrl = `https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=${process.env.firebaseAPIkey}`
// ログインモードでない場合、サインアップのURLをセット
if(!authData.isLogin) {
authUrl = `https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=${process.env.firebaseAPIkey}`
}
// ログイン/サインアップの処理
return axios.post(authUrl, {
email: authData.email,
password: authData.password,
returnSecureToken: true,
})
.then(result => {
vuexContext.commit('setToken', result.data.idToken)
})
.catch(e => console.log(e))
},
},
そして、actionを設定します。
axiosのモジュールを使っている場合は、then()ブロックはresultやresponseではなく、dataにダイレクトにアクセスできるので、result.data.idToken
ではなく、data.idToken
とすることでアクセスできます。
IDトークンによる認証
Realtime Databaseのルールを次のようにauthされている状態でないとwriteできないとします。
{
"rules": {
".read": "true",
".write": "auth != null",
}
}
その場合、ログインしているユーザーしたwriteできなくなります。
そして、上のようにIDを保持しただけでは、データを送信してもエラーが返されてしまいます。
認証されたリクエストをRealtime Database REST APIに送信するには、vuexのstateのtokenに保持したIDトークンをauth=というクエリ文字列パラメータとして渡す必要があります。
Firebase公式サイト:IDトークンによる認証によると、
"https://.firebaseio.com/users/ada/name.json?auth="
というURLのため、?auth=
というパラメーターとIDトークンを記述すればいいことがわかります。
よって、actionsで、
editPost(vuexContext, post) {
return axios.put(`${process.env.baseUrl}/posts/${post.id}.json`, オブジェクト)
...
}
という部分を下のように変更します。
editPost(vuexContext, post) {
return axios.put(`${process.env.baseUrl}/posts/${post.id}.json?auth=${vuexContext.state.token}`, オブジェクト)
...
}
stateには、vuexContextからアクセスできます。
これでIDトークンによって認証されている状態となります。
middlewareを使ってログインしていないユーザーをリダイレクトするには、middlewareを使ってログインしていないユーザーをリダイレクトする方法を参考にしてみてください。