How we hash magic links
Magic links let users log in by clicking a link in their email. No password to remember, no code to type. But behind that simplicity is a token that grants full access to an account. If you store or transmit it wrong, you've built a security hole, not a login flow.
The token lifecycle
When a user requests a magic link, Own Auth generates a cryptographically random token using Node's crypto.randomBytes. The token is 32 bytes of entropy, enough that brute-forcing it is computationally infeasible.
The raw token goes into the email link. A SHA-256 hash of the token goes into the database. When the user clicks the link, we hash the token from the URL and compare it to the stored hash. If they match, the user is logged in.
Why hash at all?
If an attacker gains read access to your database through a SQL injection, a backup leak, or a compromised admin account, they shouldn't be able to log in as any user. Storing raw tokens would give them exactly that power. Storing hashes means a database breach doesn't compromise active magic links.
Single use and expiry
Every magic link token works exactly once. After validation, the row is deleted from the database. Even if someone intercepts the link after the user clicks it, it's already dead.
Tokens also expire after a configurable window (default: 15 minutes). Expired tokens are cleaned up automatically. A magic link sitting in someone's inbox for a week is useless.
Rate limiting
Requesting a magic link triggers an email send. Without rate limiting, an attacker could use your app to spam anyone's inbox. Own Auth rate-limits magic link requests per email address and per IP, with configurable windows and thresholds.