LoginSignup
29
22

More than 5 years have passed since last update.

QuasarFramework(Vue.js) + Firebase で、ユーザーのパスワード・Emailを更新する

Posted at

Firebaseを使って、ユーザーのパスワードやEmailなどの重要情報を更新する機能を実装してみます。QuasarFramework(Vue.js)を使って実装しています。

参考

前提

Vue.js, QuasarFrameworkなどで、Firebaseに作成しているアプリなどがある。
まだの方は、以下の記事など参照にしていただけますと幸いです。
https://qiita.com/yassyskywalker/items/d74ea3b0834145df5473

パスワードを変更する(現在のパスワードを覚えている)

パスワードを更新するためのフォームを作成します。
firebaseの公式サイトですすめられていますが、再認証のプロセスをかませるのがポイントのようです。
* UserオブジェクトのEmailAuthProviderメソッドを使って、credentialを取得する
* reauthenticateWithCredential()に、credentialを渡して、再認証する

<template lang="html">
<div class="row">
  <div class="col-xs-12 col-sm-12">
    <!-- プロフィールフォーム -->
    <div class="row justify-center">
      <div class="col-6">
        <q-field
          label="現在のパスワード"
        >
          <q-input
            v-model="currentPassword"
            type="password"
            max-length='30'
          />
        </q-field>
      </div>
    </div>
    <div class="row justify-center">
      <div class="col-6">
        <q-field
          label="新しいパスワード"
        >
          <q-input
            v-model="newPassword1"
            type="password"
            max-length='30'
          />
        </q-field>
      </div>
    </div>
    <div class="row justify-center">
      <div class="col-6 text-center">
        <q-btn color="primary" class="q-btn-margin" @click="sendResetMail">パスワードを変更する</q-btn>
      </div>
    </div>
  </div>
</div>
</template>

<script>
import {
  Alert,
  QBtn,
  QField,
  QInput
} from 'quasar'
import firebase from 'firebase'
import 'quasar-extras/animate/bounceInLeft.css'
import 'quasar-extras/animate/bounceOutRight.css'

export default {
  name: 'myPageProfile',
  components: {
    QBtn,
    QField,
    QInput
  },
  data () {
    return {
      currentPassword: '',
      newPassword1: ''
      validation: {
        currentPassword: true,
        newPassword1: true
      },
      errorLabel: {
        currentPassword: '必須項目です',
        newPassword1: ''
      }
    }
  },
  computed: {
  },
  methods: {
    sendResetMail () {
      const user = firebase.auth().currentUser
      // 再認証のcredentialを取得する
      const credential = firebase.auth.EmailAuthProvider.credential(
        user.email,
        this.currentPassword
      )
      // credentialをreauthenticateWithCredentialに渡す
      user.reauthenticateWithCredential(credential).then(() => {
        // 再認証に成功した場合のみ、updatePasswordメソッドを実行する
        user.updatePassword(this.newPassword1).then(() => {
          Alert.create({
            html: 'パスワードを更新しました。再度ログインをお願いします。',
            color: 'positive',
            enter: 'bounceInLeft',
            leave: 'bounceOutRight'
          })
          this.logout()
        }).catch((error) => {
          console.log(error)
        })
      // reauthenticateWithCredentialに失敗したケース
      }).catch((error) => {
        this.validation.currentPassword = false
        this.errorLabel.currentPassword = 'パスワードが違います。'
        Toast.create.positive({
          html: '認証に失敗しました。再度パスワードのご確認をお願いします。',
          timeout: 2500
        })
      })
    },
    logout () {
      firebase.auth().signOut()
        .then(() => {
          this.$router.replace('<ログインフォームへのroute name>')
        })
    }
  }
}
</script>

パスワードを忘れてしまった場合などにメールで再設定リンクを送付する。

これは、sendPasswordResetEmailを利用すると手軽に設定できます。

<template lang="html">
  <div>
    <div class="layout-padding row justify-center background-whitesmoke items-center">
      <div class="col-xs-12 col-sm-7 col-lg-5">
        <q-card class="q-card-background-white">
          <q-card-main>
            <div class="row">
              <div class="col-sm-10 offset-sm-1 text-center">
                <img src="~assets/quasar-logo-full.svg" class="logo-sized">
              </div>
            </div>
            <div class="row">
              <div class="col-sm-10 offset-sm-1 text-left">
                <h5>パスワードをリセットする</h5>
              </div>
            </div>
            <div class="row">
              <div class="col-sm-10 offset-sm-1 text-left">
                <p style="font-size: 12px;">メールアドレスを入力してください。</p>
              </div>
            </div>
            <div class="row">
              <div class="col-sm-10 offset-sm-1">
                <q-field>
                  <q-input v-model="email" float-label="メールアドレス" color="primary" type="email"/>
                </q-field>
              </div>
            </div>
            <div class="row" style="padding-top: 20px;">
              <div class="col-sm-10 offset-sm-1 text-right">
                <q-btn color="primary" style="font-weight: bold;" @click="resetPassword">パスワードをリセットする</q-btn>
              </div>
            </div>
            <br>
            <div class="row">
              <p style="color:#027be3;font-size:12px;"><router-link :to="{ name: 'Signup' }">新規アカウント作成</router-link></p>
            </div>
            <div class="row">
              <p style="color:#027be3;font-size:12px;"><router-link :to="{ name: 'Login' }">すでにアカウントをお持ちの方はこちら</router-link></p>
            </div>
          </q-card-main>
        </q-card>
      </div>
    </div>
  </div>
</template>

<script>
import {
  Alert,
  QBtn,
  QCard,
  QCardMain,
  QField,
  QInput
} from 'quasar'
import firebase from 'firebase'
import 'quasar-extras/animate/bounceInLeft.css'
import 'quasar-extras/animate/bounceInRight.css'
import 'quasar-extras/animate/bounceOutRight.css'

export default {
  name: 'resetpassword',
  components: {
    QBtn,
    QCard,
    QCardMain,
    QField,
    QInput
  },
  data () {
    return {
      email: ''
    }
  },
  methods: {
    resetPassword () {
      firebase.auth().sendPasswordResetEmail(this.email).then(
        () => {
          Alert.create({
            html: 'ご登録のメールアドレスに再設定のリンクを送付いたしました。',
            color: 'positive',
            enter: 'bounceInLeft',
            leave: 'bounceOutRight'
          })
          this.$router.replace('/')
        },
        (err) => {
          Alert.create({
            html: 'ご登録のアドレスがございません。再度メールアドレスのご確認をお願いします。',
            color: 'negative',
            enter: 'bounceInLeft',
            leave: 'bounceOutRight'
          })
          console.log(err)
        }
      )
    }
  },
  computed: {
  }
}
</script>

<style lang="stylus">
/* .q-card-background-white
  background: white;

.background-whitesmoke
  background: whitesmoke;
  height: 100vh;

.logo-sized
  width: 150px;
  margin: 20px; */
</style>

フォームから送信して、再設定リンクが送付されれば成功です!
ただ、再設定のフォームが英語になってしまってるので、それを修正する場合は、以下のように設定するようです。
https://firebase.google.com/docs/auth/custom-email-handler?hl=ja

これも今度やってみようかと思います。

メール アクションで状態 / 続行 URL を渡す

パスワードやE-mailなどの再設定に特定のURLを渡すことが出来ます。

承認済みドメインを設定する。

続行 URL を安全に渡すには、URL のドメインが Firebase コンソールでホワイトリストに登録されている必要があります。それには、[Authentication] セクションで、[OAuth リダイレクト ドメイン] のリストにこのドメインを追加します(まだ存在しない場合)。

OAuthリダイレクトドメインは、承認済みドメインの箇所のようです。デフォルトで、localhostは設定されてるので、そのままにしておきます。

firebase.auth.ActionCodeSettings インスタンスを指定する

パスワードの再設定メールまたは確認メールを送信する際は、firebase.auth.ActionCodeSettings インスタンスを指定する必要があります。このインターフェースでは、次のパラメータを指定できます。

今回は、さきほどの、sendPasswordResetEmailを例にして設定してみます。引数として、emailと ActionCodeSettingsインスタンスを渡すことで、続行URLを実現できるようです。
https://firebase.google.com/docs/reference/js/firebase.auth.Auth

...
resetPassword () {
  const actionCodeSettings = {
    url: 'http://localhost:8080/',
    handleCodeInApp: false
  }
  firebase.auth().sendPasswordResetEmail(
    this.email, actionCodeSettings)
    .then(
      () => {
        Alert.create({
          html: 'ご登録のメールアドレスに再設定のリンクを送付いたしました。',
          color: 'positive',
          enter: 'bounceInLeft',
          leave: 'bounceOutRight'
        })
        this.$router.replace('/')
      },
      (err) => {
        Alert.create({
          html: 'ご登録のアドレスがございません。メールアドレスのご確認をお願いします。',
          color: 'negative',
          enter: 'bounceInLeft',
          leave: 'bounceOutRight'
        })
        console.log(err)
      }
    )
},
...

パスワードを再設定した後に、指定したページが表示されたら成功です!!

まとめ

Firebaseだとメール認証、パスワード再設定などのデリケートな部分も、比較的手軽に実装できて、素晴らしいですね!ますますファンになりそうです。

29
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
22