Vue.js + Firebase AuthでログインsignInWithRedirectでログインフローを作る
Vue.js + Firebase AuthでログインsignInWithRedirectでログインフローを作ろうとしたら、リダイレクト後の処理ができなくてハマったので対策まとめです。
公開日:2019年8月6日
ダメだったパターン
ネットでよく例で出ているやつです。
<template>
<div class="">
<button @click="googleLogin">Google ログイン</button>
</div>
</template>
<script>
import firebase from 'firebase/app'
export default {
created () {
},
mounted () {
},
methods: {
googleLogin: function() {
const provider = new firebase.auth.GoogleAuthProvider()
firebase.auth().signInWithRedirect(provider)
}
}
}
</script>
このパターンだと、FirebaseAuthのログイン画面に遷移して、そのまま戻ってきたら無反応になります。
以下、いろいろ試したみたことも残しておきます。
ページを読むごとに判定する
ログイン出来ているかは、
firebase.auth().onAuthStateChanged
で判定するのですが、一回一回サーバーに読み行っているようで、beforeCreateなどでonAuthStateChangedを判定すると、Google認証から戻ってくると、元のログインボタンが表示されたままのページが表示され、裏ではログイン判定をしてリダイレクトする、というとても気持ち悪い感じになりました。
これではユーザーが混乱してしまいますね。
isLoadingなどのフラグを立ててみた
isLoadingなどのフラグを用意して、Goolge認証ページに行く前にローディングに切り替えてみました。
やってみると、firebase.auth().signInWithRedirect()からリダイレクトで戻ってくると、新規でページを読み込んでいるので(ページリフレッシュ)、フラグが元に戻ってしまい、うまく出来ませんでした。
- isLoading => true
- firebase.auth().signInWithRedirect()
- ページ再読み込み -> isLoading => falseに戻る
- 画面にはログインボタンが出てきたまま
という感じです。
うまくいったやり方
ということで、お手上げか!と思ったのですが、router-viewでローディング画面に入ってしまえばいいのか?と思って、試してみたところ、これが正解でした。
流れとしては、
- サインインページ(/signin)でGoogleログインボタンを押す
- Googleページへリダイレクト(firebase.auth().signInWithRedirect())する。裏側ではサインイン中ページ(/signin/loading)へrouter.pushする(router.goではダメ)
- 認証する
- サインイン中ページ(/signin/loading)に戻ってくる
- サインイン中ページ(/signin/loading)で、firebase.auth().onAuthStateChangedでログイン判定をして、任意のページにrouter.pushする
という感じです。
具体的に各ファイルを見ていきます。main.jsでfirebaseの設定が出来ている前提です。
設定などは、こちらの記事がわかりやすいです。
router.js
signinの部分だけ抜粋です。
{
path: "/signin",
component: () => import( './views/Signin.vue'),
children: [
{
path: '',
name: "signin",
component: () => import( './views/SigninTop.vue'),
},
{
path: 'loading',
component: () => import( './views/SigninLoading.vue'),
},
]
}
Signin.vueコンポーネントの中で、子ルートをrouter-viewで切り替えてます。
Signin.vue
ログイン画面の親コンポーネントです。大事なのはrouter-viewくらいです。
<template>
<section class="container">
<h1>サインイン</h1>
<transition>
<router-view/>
</transition>
</section>
</template>
SigninTop.vue
Googleログインボタンと実行とGoogleログイン画面への遷移、そして背後ではログインローディングページへの遷移をします。
<template>
<div class="">
<button @click="googleLogin">Google ログイン</button>
</div>
</template>
<script>
import firebase from 'firebase/app'
export default {
created () {
},
mounted () {
},
methods: {
googleLogin: function() {
const provider = new firebase.auth.GoogleAuthProvider()
firebase.auth().signInWithRedirect(provider)
this.$router.push('loading')
}
}
}
</script>
SigninLoading.vue
Googleログイン画面から戻ってきたら、ログインが完了しているかをチェックして、結果によってリダイレクトするだけのページです。
<template>
<div class="">
<p>サインインしています...</p>
</div>
</template>
<script>
import firebase from 'firebase/app'
export default {
created () {
},
computed: {
},
mounted () {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
console.log('login!!');
this.$router.push('/mypage')
}else{
this.$router.push('/signin')
}
})
},
methods: {
}
}
</script>
この一連の流れで、それっぽいログイン画面ができました。
きっと、もっと良いやり方があると思うのですが、簡単にそれっぽいFirebase AuthのGoogleログイン画面ができました。
ネットの記事が「とりあえずやってみた」系が多く、実際の画面遷移なども含めて考えられた記事が少なかったので、ノートにしてみました。
ご参考になれば幸いです!!
新着ノート
-
NUXT3
公開日:2023年2月16日
-
NUXT3
公開日:2023年1月30日
新着コード
-
Vue.js
公開日:2022年4月18日
-
Vue.js
公開日:2022年4月13日