Passwordless & Passkeys — Auth

Passwordless authentication menghilangkan password sama sekali. Passkeys adalah implementasi modern yang menggunakan kriptografi kunci publik dan biometrik pera

Passwordless authentication menghilangkan password sama sekali. Passkeys adalah implementasi modern yang menggunakan kriptografi kunci publik dan biometrik perangkat.

Mengapa password bermasalah:

Metode Passwordless:

1. Magic Link Server kirim link sekali pakai via email:

// Generate token
const token = crypto.randomBytes(32).toString("hex");
await db.save({ token, userId, expiresAt: Date.now() + 15 * 60000 });

// Kirim email
await sendEmail(user.email, `Klik untuk login: https://app.com/auth?token=${token}`);

// Verifikasi
app.get("/auth", async (req, res) => {
  const record = await db.findToken(req.query.token);
  if (!record || record.expiresAt < Date.now()) return res.status(400).send("Token tidak valid");
  await db.deleteToken(record.token); // hapus setelah dipakai!
  req.session.userId = record.userId;
  res.redirect("/dashboard");
});

2. Passkeys (WebAuthn) Menggunakan pasangan kunci kriptografi: private key disimpan di device (tidak pernah keluar), public key disimpan di server.

Alur Registrasi Passkey:

1. Server kirim challenge (random bytes)
2. Device (TouchID/FaceID/Windows Hello) tanda-tangani challenge dengan private key
3. Server simpan public key user

Alur Login Passkey:

1. Server kirim challenge baru
2. User verifikasi biometrik di device
3. Device tanda-tangani challenge dengan private key → kirim signature
4. Server verifikasi signature dengan public key → login berhasil!
// Registrasi (menggunakan @simplewebauthn/server)
const options = await generateRegistrationOptions({
  rpName: "BelajarWeb.dev",
  rpID: "belajarweb.dev",
  userName: user.email,
  authenticatorSelection: {
    residentKey: "preferred",
    userVerification: "preferred",
  }
});
// Simpan options.challenge di session, kirim ke client

// Verifikasi registrasi
const verification = await verifyRegistrationResponse({
  response: req.body,
  expectedChallenge: session.challenge,
  expectedRPID: "belajarweb.dev",
  expectedOrigin: "https://belajarweb.dev",
});
// Simpan verification.registrationInfo.credentialPublicKey

Keunggulan Passkeys:

Status adopsi (2025): Google, Apple, Microsoft, GitHub, Shopify, dan ribuan layanan lain sudah mendukung passkeys. Browser modern semua sudah support WebAuthn API.