Magic Link Authentication — Auth

Magic link menghilangkan password: user memasukkan email, server mengirim tautan sekali pakai. Klik tautan → langsung login. Slack, Notion, Substack memakai pol

Magic link menghilangkan password: user memasukkan email, server mengirim tautan sekali pakai. Klik tautan → langsung login. Slack, Notion, Substack memakai pola ini.

Keuntungan:

Kelemahan:

Alur lengkap:

1. User input email: "[email protected]"
2. Server generate token random (32 bytes), simpan hash + expiry + emailnya
3. Server kirim email: "Klik untuk login: https://app.com/auth/magic?token=xyz"
4. User klik link dalam 15 menit
5. Server cek: token valid? belum kadaluarsa? belum digunakan?
6. Jika valid: buat session + tandai token sebagai consumed
7. Redirect ke dashboard

Implementasi server:

async function requestMagicLink(email) {
  const token = crypto.randomBytes(32).toString("hex");
  const tokenHash = await bcrypt.hash(token, 10); // jangan simpan raw token!
  const expiresAt = Date.now() + 15 * 60 * 1000;  // 15 menit

  await db.magicLinks.insert({
    email, tokenHash, expiresAt, consumedAt: null,
  });

  await sendEmail(email, `https://app.com/auth/magic?token=${token}`);
}

async function verifyMagicLink(token) {
  const records = await db.magicLinks.findByExpiryAfter(Date.now());
  for (const record of records) {
    if (record.consumedAt) continue;
    if (await bcrypt.compare(token, record.tokenHash)) {
      await db.magicLinks.markConsumed(record.id);
      return record.email; // login berhasil
    }
  }
  return null;
}

Aturan keamanan yang WAJIB:

1. Token hanya sekali pakai — setelah diklik, invalidate permanent. Jika klik lagi → error.

2. Short expiry — maksimal 15 menit. Token yang lama tersisa di inbox adalah liability.

3. Simpan hash, bukan token mentah — jika DB bocor, penyerang tidak dapat token valid.

4. Rate limiting per email — cegah spam email dan enumeration attack.

5. Token panjang (≥32 bytes random) — anti-brute force.

6. Constant-time comparison — cegah timing attack.

Bonus: session fixation

Setelah magic link berhasil, buat session ID baru (jangan reuse session sebelumnya). Ini mencegah skenario di mana penyerang "menyiapkan" session lalu mengundang korban login ke session itu.