Firebase Authenticationでパスワードの再設定をする
Firebase Authenticationでユーザー情報の管理をしている。
パスワードの再設定する時のメモ。
Firebaseのデフォルトの新パスワード設定を利用する場合
この場合は、
- 登録しているメールアドレスにメールが届く
%DISPLAY_NAME% 様
メールアドレスを確認するには、次のリンクをクリックしてください。
https://<project id>.firebaseapp.com/__/auth/action?mode=action&oobCode=code
このアドレスの確認を依頼していない場合は、このメールを無視してください。
よろしくお願いいたします。
%APP_NAME% チーム
- リンクをクリックすると以下の画面が開く
(「続行」ボタンは actionCodeSettings
を設定した場合のみ表示される。)
実装
関数としては、sendPasswordResetEmail
を利用する。この関数を呼び出すことで、第一引数のメールアドレスに、firebase authのurlでパスワード設定する画面へ誘導できる。
const submitPasswordResetEmail = async () => {
await auth
.sendPasswordResetEmail(email)
.then((resp) => {
// メール送信成功
})
.catch((error) => {
// メール送信失敗
console.log(error)
})
}
第二引数として、actionCodeSettings
を設定できる。これは、firebase authのurlでパスワードを再設定した後にリダイレクトする情報など付与できる。以下の場合、「続行」ボタンが現れ、それをクリックするとhttp://localhost:3000/login
に遷移させることができる。
const submitPasswordResetEmail = async () => {
const actionCodeSettings = {
// パスワード再設定後のリダイレクト URL
url: 'http://localhost:3000/login',
handleCodeInApp: false,
}
await auth
.sendPasswordResetEmail(email, actionCodeSettings)
.then((resp) => {
// メール送信成功
})
.catch((error) => {
// メール送信失敗
console.log(error)
})
}
ちなみにこの場合、パスワード再設定用のGetパラメータにcontinueUrl
が追加される。これはもちろん、actionCodeSettings
のurl
プロパティで登録したもの。
https://<project ID>.com/__/auth/action?mode=resetPassword&oobCode=3zakKRxy5adKhTMX5kC81Kl0jKkit-YY4HRSUMeXagwAAAF8KwNVCw&apiKey=AIzaSyA9J-hMBpQkXViG6i2T52kIKLWX6w9cQpQ&continueUrl=http%3A%2F%2Flocalhost%3A3000%2Flogin&lang=ja
カスタマイズのパスワード再設定画面を使う場合
最初のパターンだと、firebaseのデフォルトであるものの、サービスの画面が出てこないためユーザーの不安を感じさせてしまう。そこでサービス独自のパスワード再設定画面を作りたい。
Firebase Authenticationでパスワード再設定画面のURLを自分の指定するURLに設定できる機能があり、
- アクションURLで、自分のサービスのパスワード再設定画面のURLを登録
- パスワード再設定画面でfirebase authの関数を色々呼び出す
ことで、実装ができる。
Firebase Authenticationの画面からアクションURLを設定する
アクションURLはもともと、https://<project ID>.firebaseapp.com/__/auth/action
になっている。
[パスワードの再設定] > 編集ボタンを押し、画面下部のアクションURLを編集する。
今回、開発用に例えばhttp://localhost:3000/set-new-password
などとする。
その結果、メール再設定用のメールの本文のリンクが以下のように変更される。
http://localhost:3000/set-new-password?mode=resetPassword&oobCode=WOBTj7bYcSLCWtWgwrt7dlNYgW_zlVbLUdQq0r_qmCsAAAF8Kvo8bA&apiKey=AIzaSyA9J-hMBpQkXViG6i2T52kIKLWX6w9cQp&lang=ja
これをクリックすると、http://localhost:3000/set-new-password
に遷移する。
次にその画面の実装を見ていく。
実装
-
verifyPasswordResetCode
関数 -
confirmPasswordReset
関数
を使う。
今回はReactで作った画面の例だが、set-new-password.tsx
は以下。
const NewPassword = () => {
const [actionCode, setActionCode] = useState<string>('')
const [password, setPassword] = useState<string>('')
// 初回のレンダリングのみ
useEffect(() => {
const queryParams = new URLSearchParams(window.location.search)
const oobCode = queryParams.get('oobCode') || ''
setMode(mode)
setActionCode(oobCode)
}, [])
const handleSubmit = (event: React.SyntheticEvent) => {
event.preventDefault()
if(oobCode === '') return // 取得できない場合処理終了
firebase
.auth()
.verifyPasswordResetCode(actionCode)
.then(() => {
firebase
.auth()
.confirmPasswordReset(actionCode, password)
.then(async (resp) => {
console.log("success")
// 成功。ログイン画面などを表示するコードを足す場所
})
.catch((error) => {
console.log(error)
})
})
}
return(
// 略
)
やっていることとしては、
- URLのGetパラメータから
oobCode
と取得する。 -
verifyPasswordResetCode
関数でoobCode
が妥当か検証する。 - 妥当だった場合、
confirmPasswordReset
関数にoobcode
を渡して新しいパスワードを登録。
oobCode
は、メールアドレスの所有者だけが知っている、時間制限付きのトークン。
The confirmation code send via email to the user.
verifyPasswordResetCode
関数は以下の場合エラーを投げるようになっているので、後続の処理をしないようにできる。
- トークンの有効時間を超えた場合
- トークンが間違っていたり、最新のものではない
- Firebase Authのユーザーがdisabledになっている
- アカウントが無効になっている
- アカウントが削除されている
verifyPasswordResetCode
関数が正常に動作するとemailアドレスを取得可能。
参考
あとから調べると、以下の記事に書かれていた。
Discussion