hectoday
DocsCoursesChangelog GitHub
DocsCoursesChangelog GitHub

Access Required

Enter your access code to view courses.

Invalid code

← All courses Two-Factor and Passwordless Auth with @hectoday/http

Why Passwords Are Not Enough

  • The Problem with Passwords
  • Project Setup

TOTP (Time-Based One-Time Passwords)

  • How TOTP Works
  • Generating Secrets and QR Codes
  • Enabling 2FA on an Account
  • Verifying TOTP on Login
  • Time Windows and Clock Drift

Recovery

  • Recovery Codes
  • Disabling 2FA
  • Account Recovery When Everything Is Lost

Magic Links

  • How Magic Links Work
  • Building Magic Link Login
  • Security Considerations

WebAuthn and Passkeys

  • What Are Passkeys?
  • Registration Flow
  • Authentication Flow
  • Passkeys as Second Factor or Primary

Putting It All Together

  • Multi-Method Auth
  • Auth Method Checklist and Capstone

How TOTP Works

The algorithm in plain English

TOTP (Time-Based One-Time Password) generates a 6-digit code from two inputs: a shared secret and the current time. Both the server and the user’s authenticator app have the same secret and the same clock, so they both compute the same code at the same time.

Here is the full process:

  1. The server generates a random secret (a 20-byte random string, base32-encoded)
  2. The server shares the secret with the user (via a QR code)
  3. The user’s authenticator app stores the secret
  4. When a code is needed, both sides compute: HMAC-SHA1(secret, floor(time / 30))
  5. The HMAC output is truncated to a 6-digit number
  6. The server compares its computed code with the user’s submitted code

The floor(time / 30) is what makes the code change every 30 seconds. Both sides divide the current Unix timestamp by 30 and round down. For the same 30-second window, they get the same integer, which produces the same HMAC, which produces the same 6-digit code.

Why it works without a network connection

The authenticator app does not contact the server to get the code. Both sides compute the code independently from the same inputs (secret + time). This means TOTP works offline — on a plane, in a basement, anywhere. The only requirement is that the phone’s clock is reasonably accurate.

Why the code is short-lived

A TOTP code is valid for one 30-second window. Even if an attacker intercepts the code (by watching the screen, for example), they have at most 30 seconds to use it. After that, a new code is required.

Compare this to a password, which is valid until the user changes it — potentially months or years.

The secret is the real credential

The 6-digit code is ephemeral. The secret is the real credential. If the attacker obtains the secret, they can generate valid codes forever. This is why:

  • The secret is shown to the user exactly once (at setup, via QR code)
  • The secret is stored encrypted or securely on the user’s device
  • The secret is never transmitted after setup (only the derived codes are sent)

On the server side, we store the secret in the database. If the database is breached, the attacker has the secrets and can generate codes for every user. This is a known limitation — in production, encrypt the secrets at rest or use a hardware security module (HSM).

[!NOTE] For this course, we store the TOTP secret in plain text in the database. In production, encrypt it with a key stored in an environment variable or a secrets manager. The encryption is separate from the TOTP algorithm — it is standard data-at-rest encryption.

Exercises

Exercise 1: Calculate the current TOTP time step manually. Take the current Unix timestamp (in seconds), divide by 30, and floor it. This number is what both the server and the authenticator use to generate the code.

Exercise 2: If the current time step is T, what are the values for the previous and next windows? (Answer: T-1 and T+1.)

Why does TOTP work without a network connection between the authenticator app and the server?

← Project Setup Generating Secrets and QR Codes →

© 2026 hectoday. All rights reserved.