Email + Password
Email + password is the baseline auth method. Pair it with email verification, password reset, and rate limiting; the rest of your app reads auth.currentUser.
Sign up + sign in + verification + reset
EXAMPLE
import { initializeApp } from 'firebase/app';
import {
getAuth,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
sendEmailVerification,
sendPasswordResetEmail,
confirmPasswordReset,
verifyPasswordResetCode,
applyActionCode,
updatePassword,
reauthenticateWithCredential,
EmailAuthProvider,
onAuthStateChanged,
signOut,
updateProfile,
} from 'firebase/auth';
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
// 1) Sign up
async function signup(email, password, displayName) {
const { user } = await createUserWithEmailAndPassword(auth, email, password);
await updateProfile(user, { displayName });
await sendEmailVerification(user, {
url: 'https://app.example.com/verified',
handleCodeInApp: false,
});
return user;
}
// 2) Sign in
async function login(email, password) {
try {
const { user } = await signInWithEmailAndPassword(auth, email, password);
if (!user.emailVerified) {
// Optional: block unverified users from sensitive features
}
return user;
} catch (e) {
// Common error codes — surface friendly messages
switch (e.code) {
case 'auth/invalid-credential': throw new Error('Invalid email or password');
case 'auth/too-many-requests': throw new Error('Try again in a few minutes');
case 'auth/user-disabled': throw new Error('Account suspended');
default: throw e;
}
}
}
// 3) Listen for state changes
const unsub = onAuthStateChanged(auth, (user) => {
if (user) {
store.set({ uid: user.uid, email: user.email, verified: user.emailVerified });
} else {
store.clear();
}
});
// 4) Password reset — request
async function requestReset(email) {
await sendPasswordResetEmail(auth, email, {
url: 'https://app.example.com/reset-done',
});
}
// 5) Password reset — apply on the reset page
async function applyReset(oobCode, newPassword) {
const email = await verifyPasswordResetCode(auth, oobCode);
await confirmPasswordReset(auth, oobCode, newPassword);
return email;
}
// 6) Email verification — apply the code
async function applyVerification(oobCode) {
await applyActionCode(auth, oobCode);
}
// 7) Update password (re-authenticate first for sensitive ops)
async function changePassword(currentPassword, newPassword) {
const user = auth.currentUser;
const cred = EmailAuthProvider.credential(user.email, currentPassword);
await reauthenticateWithCredential(user, cred);
await updatePassword(user, newPassword);
}
// 8) Sign out
async function logout() { await signOut(auth); }
// 9) Resend verification
async function resendVerification() {
if (auth.currentUser && !auth.currentUser.emailVerified) {
await sendEmailVerification(auth.currentUser);
}
}
// 10) Action handler page (one URL for verify, reset, recover-email)
// In Firebase Console → Authentication → Templates → set Action URL:
// https://app.example.com/action?mode=&oobCode=&apiKey=
// Implement /action page that dispatches by mode:
import { applyActionCode, verifyPasswordResetCode, confirmPasswordReset } from 'firebase/auth';
async function handleAction(mode, oobCode, newPassword) {
switch (mode) {
case 'verifyEmail': return applyActionCode(auth, oobCode);
case 'resetPassword': return confirmPasswordReset(auth, oobCode, newPassword);
case 'recoverEmail': return applyActionCode(auth, oobCode);
}
}
// 11) Hardening checklist
// • Require email verification before sensitive actions
// • Use App Check (https://firebase.google.com/docs/app-check) to reject bot traffic
// • Rate limit signup + password reset — via Firebase rules or a Cloud Function
// • Always verify ID tokens server-side (don't trust the client uid)
// • Pair with MFA (TOTP) for high-value accounts
// • Customise email templates with branding + security warnings
// • Track failed login attempts; lock account / send alert after threshold
// 12) Security best practices
// • Password requirements: enforce in Firebase Console (length, classes)
// • Detect leaked passwords: check HaveIBeenPwned on signup
// • Periodic re-authentication for sensitive UI
// • Server-verified email-only logins instead of token-only sessions
Why it matters
Firebase Auth handles the boring-but-critical email-verification + password-reset flows for you. The piece you add: enforce email verification before privileged actions, and re-authenticate the user before password / email changes.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
import { createUserWithEmailAndPassword, signInWithEmailAndPassword } from 'firebase/auth';
await createUserWithEmailAndPassword(auth, 'ada@example.com', 's3cret');
await signInWithEmailAndPassword(auth, 'ada@example.com', 's3cret');
Try it Yourself »
Exercise
Sign in with email + password.
await
(auth, email, pw);
camelCase, starts with signIn.
Discussion
Loading…