iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

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);

Discussion

Loading…