Password-based authentication has a serious problem: users forget passwords, reuse them across sites, and get phished. Magic links solve this elegantly — the user enters their email, receives a one-click sign-in link, and is authenticated without ever setting a password. This guide explains how magic links work, when to use them, and how to implement them in a Next.js app with Vaultix-ID.
How Magic Links Work
The flow is straightforward:
- User enters their email address on your sign-in page
- Server generates a cryptographically random, time-limited token (typically 15 minutes)
- Server stores a hash of the token and emails the user a link:
https://yourapp.com/auth/verify?token=abc123 - User clicks the link — server verifies the token, creates a session, and redirects the user
- Token is immediately invalidated (single-use)
The security model relies on email as the second factor: only someone with access to the email inbox can authenticate. This is often more secure than passwords in practice, since password breaches are far more common than email account compromises.
Magic Links vs Passwords vs OTP Codes
| Factor | Password | Email OTP code | Magic link |
|---|---|---|---|
| Phishing resistance | Low | Medium | High |
| User friction | Medium (remember password) | Medium (switch to email, type code) | Low (one click) |
| Mobile UX | Good | Good | Excellent |
| Requires email access | No | Yes | Yes |
| Works offline | Yes | No | No |
| Implementation complexity | Medium | Medium | Medium |
Implementing Magic Links with Vaultix-ID
Step 1: Trigger the magic link
// app/sign-in/page.tsx (client component)
"use client";
import { useState } from "react";
export default function SignInPage() {
const [email, setEmail] = useState("");
const [sent, setSent] = useState(false);
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
await fetch("https://your-vaultix.vercel.app/v1/magic-link", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-publishable-key": process.env.NEXT_PUBLIC_VAULTIX_PUBLISHABLE_KEY!,
},
body: JSON.stringify({ email }),
});
setSent(true);
}
if (sent) return <p>Check your email for a sign-in link!</p>;
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={email}
onChange={e => setEmail(e.target.value)}
placeholder="you@example.com"
required
/>
<button type="submit">Send magic link</button>
</form>
);
}Step 2: Handle the callback
Vaultix-ID handles the token verification and session creation automatically. The magic link points to the hosted callback page, which then redirects to your app with the session cookie set.
// In your Vaultix-ID dashboard, configure the redirect URL:
// After magic link verification → redirect to https://yourapp.com/dashboard
// The SDK middleware then picks up the session automatically:
// middleware.ts
import { authMiddleware } from "@vaultix.ai/nextjs";
export default authMiddleware({ publicRoutes: ["/", "/sign-in"] });Step 3: Read the authenticated user
// app/dashboard/page.tsx
import { currentUser } from "@vaultix.ai/nextjs/server";
import { redirect } from "next/navigation";
export default async function Dashboard() {
const user = await currentUser();
if (!user) redirect("/sign-in");
return (
<div>
<h1>Welcome back, {user.firstName ?? user.emailAddresses[0].email}!</h1>
</div>
);
}Security Considerations
- Short TTL: magic link tokens should expire in 15–30 minutes. Vaultix-ID uses 15 minutes by default.
- Single-use: once a token is clicked, it must be immediately invalidated. Replay attacks are prevented at the DB level.
- Rate limiting: limit magic link requests to prevent email flooding — max 3 requests per 10 minutes per email address.
- Secure link format: the token in the URL should be cryptographically random (min 32 bytes). Never use sequential IDs.
- HTTPS only: magic links should only be sent and clicked over HTTPS to prevent interception.
Magic links work especially well for B2B SaaS where your users are employees with managed email accounts. Employees won't forget their password (they don't have one), and IT teams appreciate not having to reset passwords.
When NOT to Use Magic Links
- Shared email accounts: if multiple people share a mailbox, anyone can sign in
- High-frequency usage: users who sign in 10+ times daily will find waiting for email annoying — offer password or passkey as an alternative
- Environments with slow email delivery: if your transactional email provider has delays, the UX suffers
Conclusion
Magic links offer an excellent balance of security and user experience for most web applications. Combined with TOTP MFA for high-security accounts, passwordless authentication significantly reduces your attack surface and eliminates password-related support requests. Vaultix-ID supports magic links out of the box — start building for free.