開発している積読ハウマッチで、Googleアカウントでのログインに対応した際、
Firebase Authの認証フローをポップアップからリダイレクトに変えてみた。
ポップアップだと、どこでもログインできたけど、
ログイン画面だと元のページに戻りたく、いろいろ考えたときの備忘録。
こんな感じ
どのページから来たかを覚えておけばいいかなと思ったので、
beforeRouteEnter
で、前のページのパスを取得- クエリパラメタに付与しておく
- 認証後にクエリパラメタがあったら、そのパスに遷移
という感じにしてみた。
まずはパッケージのインストール
$ npm i firebase firebaseui firebaseui-ja
ソースはこんな感じ。
<template> <div class="container"> <div id="firebaseui-auth-container" /> </div> </template> <script lang="ts"> import { Component, Vue } from "nuxt-property-decorator"; // 初期化済みのfirebaseインスタンス。詳細は略 import firebase from "~/plugins/firebase"; // Firebase UI import * as firebaseui from "firebaseui-ja"; // CSSのインポート。これがないとレイアウトが崩れる require("firebaseui-ja/dist/firebaseui.css"); @Component export default class LoginPage extends Vue { private beforePath: string | null = null; asyncData({ store, redirect, query }) { let path = null; if (!!query.next) { // クエリパラメタが存在したら取得する path = query.next.replace(/%2F/g, "/"); } return { beforePath: path } } beforeRouteEnter(to, from, next) { // Vueコンポーネントにアクセスする場合は、nextのコールバック内で行う。 next(component => { if (!!from.name && from.name != "index") { // パスに'/'が入っているので置き換え(エンコード) const path = from.path.replace(/\//g, "%2F"); // '/login?next=<前のパス>'になるように設定 component.$router.push({ query: { next: path } }); } }); } mounted() { const auth = firebase.auth(); const ui = firebaseui.auth.AuthUI.getInstance() || new firebaseui.auth.AuthUI(auth); const uiConfig: firebaseui.auth.Config = { callbacks: { // 認証成功時のコールバック signInSuccessWithAuthResult: ( authResult: firebase.auth.UserCredential, redirectUrl: string ) => { // 戻り先が存在したら、遷移する if (!!this.beforePath) this.$router.push(this.beforePath) // firebase UI側でリダイレクトしないようにfalseを返す return false; }, // 認証成功時のコールバック signInFailure: async (error: firebaseui.auth.AuthUIError) => { console.warn("signInFailure", error); }, // UI表示時のコールバック uiShown: () => { console.info("uiShown"); } }, signInFlow: "redirect", signInOptions: [ firebase.auth.TwitterAuthProvider.PROVIDER_ID, firebase.auth.GoogleAuthProvider.PROVIDER_ID ], tosUrl: "...", // 利用規約のURL privacyPolicyUrl: "..." // プライバシーポリシーのURL }; // Firebase UIを表示させたいIDを指定する ui.start("#firebaseui-auth-container", uiConfig); } } </script>
Firebase Authのリダイレクトだと、
- 各プロバイダの認証画面に遷移
- ログイン画面に再アクセス
となるので、Storeにもデータを残せない。。
ただ、クエリパラメタをつけておくと、
クエリパラメタつけたままログイン画面に戻ってくるので、それを利用。
また、signInSuccessUrl
を設定しておけばいいかと思ったら、
signInSuccessWithAuthResult
がPromiseを返せないのでこんな感じに。
認証成功時に、Firestoreにあるデータをロードしたかったので、ちょっと手間っぽい。
以上!!
参考にしたサイト様
- FirebaseUI でウェブアプリに簡単にログイン機能を追加する | Firebase
- firebaseui-web/README.md at master · firebase/firebaseui-web
- FirebaseUI + vueでログイン処理 - Qiita
- JavaScript を使用してアカウントに複数の認証プロバイダをリンクする | Firebase
- Vuetify + Firebase UI で簡単にログイン機能を追加とナビゲーションメニュー - グロブ
- beforeRouteEnterのnextに渡したコールバックはmountedよりも後に呼ばれる | Qrunch(クランチ)
- vue-vue-router-nuxt-hooks/index.vue at f8047b7ed898e2eeab6140ddd1dc9783e9995a6d · ryotah/vue-vue-router-nuxt-hooks