🔏
【Next.js】Firebase Authentication でパスワードの変更を実装する
はじめに
当記事は会員機能実装にあたり調査していく上で適当なパスワード変更のサンプルを探しても現在の環境に丁度よく流用できそうなものが見当たらなかったため執筆に至りました。
前提
- Next.js v9 以降
- TypeScript v4.2.3
- Firebase v9
この記事で利用している各技術の詳細な説明は省きます。
利用例
パスワード変更機能にも様々あると思いますが、今回は「現在のパスワード」と「新しく設定するパスワード」を渡す形式を採用することとします。
使い方としては旧パスワードと新パスワードを渡すと Promise<void> が返ってきて何かあったら catch できるくらい簡単な使用感を目指します。
バリデーションやエラーチェックは適宜行ってください。
import { updatePassword } from "path/to/logic";
export const Form = () => {
const handleSubmit = async (oldPassword: string, newPassword: string) => {
// パスワード更新処理
await updatePassword(oldPassword, newPassword)
.then(() => {
// 成功時処理
}).catch((e) => {
// エラー処理
});
};
return (
<div>
<button
onClick={() => {
handleSubmit("hoge", "fuga");
}}>パスワード変更</button>
</div>
);
};
実装
下記の記事を参考にして、同じ使用感でパスワード変更のメソッドを追加する方針にしています。
※ディレクトリ名は一例です
// auth/app.ts
import { initializeApp } from "firebase/app";
const firebaseConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
};
const firebaseApp = initializeApp(firebaseConfig);
export default firebaseApp;
// auth/index.ts
import {
EmailAuthProvider,
getAuth,
reauthenticateWithCredential,
updatePassword as firebaseUpdatePassword,
} from "firebase/auth";
import firebaseApp from "./app";
export const updatePassword = (
oldPassword: string,
newPassword: string
): Promise<void> => {
return new Promise((resolve, reject) => {
const auth = getAuth(firebaseApp);
if (auth.currentUser == null) {
return reject();
}
// クレデンシャルの取得
const credential = EmailAuthProvider.credential(
auth.currentUser.email || "",
oldPassword
);
// メールアドレスの再認証
reauthenticateWithCredential(auth.currentUser, credential)
.then((userCredential) => {
// パスワードの更新
firebaseUpdatePassword(userCredential.user, newPassword)
.then(() => resolve())
.catch((error) => reject(error));
})
.catch((error) => reject(error));
});
};
特筆するようなことはありませんが、クレデンシャルの取得、メールアドレスの再認証、パスワードの更新を順に処理しています。
※ firebase/auth/updatePassword をインポートする際のエイリアスは命名の都合なので必須ではありません、お好みでどうぞ。
Discussion