On this page8 sections
The safe way to add authentication to your app is to use a proven auth service or library, not a password system that you or your AI agent wrote. Offer passkeys or social login, keep the session in a secure cookie, and have the server check who the user is and what they own on every request.
That last step is the easy one to miss. The login screen works, but the data behind it answers anyone who asks directly. This guide covers the choices, the session basics and the tests that catch those gaps.
- Do not write your own password system. Use a hosted service such as Clerk, Auth0, Supabase Auth, Firebase Authentication or WorkOS, or a maintained library such as Better Auth.
- Free tiers cover 25,000 to 1 million monthly users as of September 2026.
- Offer passkeys or social login first. If you keep passwords, follow NIST’s current rules, including a 15-character minimum.
- Keep sessions in HttpOnly, Secure, SameSite cookies, and let only the server decide who is signed in.
- Test like an attacker: call your API signed out, and try to open one user’s data as another.
Why you should never build your own password system
A login form looks like two fields and a button. Behind it sits a list of jobs that each have a known way to fail:
Storing passwords with a slow, salted hashing algorithm, never as plain text or a fast hash.
Reset links that expire, work once and do not reveal whether an email has an account.
Limits on repeated guesses, so nobody can try a million passwords.
Email verification, account recovery and multi-factor authentication.
Sessions that expire, and that end on the server when someone signs out.
The rules have changed, too. NIST’s current guidance says a password used on its own must be at least 15 characters. It forbids rules like “must include a symbol” and forced periodic changes, and it requires checking new passwords against a blocklist of common and breached ones. Older tutorials still teach the opposite, and code copied from them inherits the mistakes.
A good auth provider handles all of this and patches it when attacks change. Your job shrinks to choosing one and wiring it in correctly.
Which auth service should you use in 2026?
All of these are sound choices. The differences are price at scale, how much they do for you, and where your user records live. Free tiers as of September 2026, from each provider’s pricing page:
| Option | Free tier | First paid step | Best for |
|---|---|---|---|
| Clerk (hosted) | 50,000 monthly retained users per app | Pro: $25 a month, or $20 billed yearly | React and Next.js apps that want ready-made screens |
| Auth0 (hosted) | 25,000 monthly active users | Essentials: from $35 a month for 500 users | Apps that expect enterprise needs later |
| Supabase Auth (hosted) | 50,000 monthly active users | Pro: $25 a month, 100,000 users included | Apps already using Supabase |
| Firebase Authentication (hosted) | 50,000 monthly active users | Pay as you go; SMS codes cost extra | Mobile apps and Firebase projects |
| WorkOS AuthKit (hosted) | 1 million monthly active users | Enterprise SSO: $125 per connection a month | Business software sold to larger companies |
| Better Auth (library) | Free and open source (MIT) | Your own hosting and database | Developers who want full control |
Read the small print on “user.” Clerk counts someone only if they come back at least a day after signing up. It also keeps passkeys, multi-factor authentication and branding removal for Pro.
Hosted or library? A hosted service is fastest and keeps up with new attacks for you, but you pay per user at scale and your user records live with the vendor. A library keeps users in your own database at no cost, but you own the updates, the emails and the rate limits.
One more change: Auth.js, long the default library for Next.js, has been maintained by the Better Auth team since September 2025. That team recommends Better Auth for new projects.
Passkeys, magic links or social login?
Passkeys can sync across a person’s devices through their passkey provider, and they are becoming familiar:
| Method | How it works | Watch out for |
|---|---|---|
| Passkeys | Fingerprint, face or PIN on the user’s device | Some users do not know them yet, so keep a fallback |
| Social login | “Continue with Google”, Apple or GitHub | Users who lose that account lose access |
| Magic links or email codes | A link or code sent by email | Only as safe as the inbox, and slow when email is delayed |
| Passwords | The familiar option | Need length, a breach check and ideally a second factor |
A sensible default for a new app: social login plus passkeys, with an email code as the fallback. If your audience allows it, skip passwords entirely.
How to add authentication to your app in five steps
Choose one provider and follow its quickstart
Pick from the table and use the provider’s own guide for your framework. Paste that link into your agent’s instructions, so it follows the current setup rather than an older version it remembers.
Turn on two sign-in methods
Enable them in the provider’s dashboard, such as Google and passkeys. Start small. Every extra method is another flow to test.
Protect API routes on the server
Hiding a button is not protection. Every route that returns or changes private data must check the session on the server and refuse requests without one.
Link your data to the user ID from the session
Store the provider’s user ID on every row a user owns. When a request arrives, take that ID from the verified session, never from the request body or the URL.
Keep secret keys on the server
Providers give you a public key for the browser and a secret key for the server. The secret belongs in environment variables only. Our guide to keeping API keys safe shows how.
Sessions in plain English
Because the token is the key to the account, how it is stored matters. This is the cookie Better Auth 1.7.5 sets by default when a user signs up on an HTTPS site, with the token removed:
set-cookie: __Secure-better-auth.session_token=<token>; Max-Age=604800; Path=/; HttpOnly; Secure; SameSite=LaxEach attribute does a job. HttpOnly hides the cookie from page scripts, so an injected script cannot steal it. Secure sends it only over HTTPS. SameSite=Lax keeps it off most requests started by other websites, which blocks a class of forgery attacks. Max-Age=604800 ends it after seven days.
OWASP’s session guidance adds three rules worth checking. Issue a fresh session ID at login. Make sign-out end the session on the server, not just delete the cookie. And choose lifetimes on purpose: shorter for admin panels and anything that moves money.
What to check in AI-written auth code
Agents are good at wiring up a provider’s SDK. The mistakes tend to sit around it:
Protected screens, open API. The page redirects signed-out visitors, but the API behind it still returns data to anyone.
Trusting the browser. A user ID read from the request body or URL instead of the session.
Missing ownership checks.
/api/invoices/42returns invoice 42 to any signed-in user, not only its owner.Tokens in localStorage. Any script on the page can read them. An HttpOnly cookie cannot be read that way.
Homemade security.
Math.random()for tokens, or a fast hash such as MD5 for passwords.Checks switched off “for testing”. Email verification off, rate limits removed, or cross-site requests allowed from anywhere.
If your data lives in Supabase, row-level security is a second lock behind login. Our guide to choosing a database shows it working.
Review every file that handles sign-in, sessions or access to user data. For each API route, tell me: 1. Does it check the session on the server before doing anything else? 2. Where does the user ID come from: the verified session, or something the browser sent? 3. Does it confirm the signed-in user owns the record being read or changed? Also flag tokens in localStorage, secret keys reachable from client code, homemade token or password handling, and any security check disabled "for now". List problems as file and line, most severe first. Do not fix anything yet.
For the wider picture, see our checklist for securing AI-generated code.
Test your login like an attacker
Ten minutes of hostile testing catches many of these gaps. Start with the API. Call a protected route with no session:
# Swap in one of your app's protected routes
curl -i http://localhost:3000/api/accountA protected route answers like this (other headers trimmed):
HTTP/1.1 401 Unauthorized
content-type: application/json
{"error":"Not signed in"}A 200 with data means anyone who finds that route can read it. Then work through the rest by hand:
FAQ
Is it safe to let AI write my login code?
Yes, if it wires up a proven provider and you check the result. Let it write the integration, never the security itself: no homemade password storage, tokens or session handling. Then run the attacker checks before launch.
Should I use JWTs or sessions?
For most web apps, a session in an HttpOnly cookie is simpler and easier to cancel. JWTs, signed tokens the server can check without a database lookup, suit some APIs, but they are hard to revoke early. Keep them short-lived if you use them.
Do I need multi-factor authentication?
Offer it, and require it for admin accounts. A passkey already needs both the user’s device and their fingerprint, face or PIN, which covers much of what a second factor is for. Check your plan, since some providers charge for MFA.
How much does login cost for a small app?
Usually nothing at first. The free tiers above cover 25,000 to 1 million monthly users as of September 2026. Costs arrive with growth, SMS codes, enterprise single sign-on or removing the provider’s branding.
Next, add payments to your app, or follow the whole path from idea to paying user.
- Pricing, Clerk, September 2026
- Pricing, Auth0, September 2026
- Pricing, Supabase, September 2026
- Firebase pricing plans, Google, September 2026
- Pricing, WorkOS, September 2026
- Auth.js joins Better Auth, Better Auth, September 2025
- better-auth/better-auth, GitHub, September 2026
- SP 800-63B-4: Authentication and authenticator management, NIST, August 2025
- Passkeys, FIDO Alliance, September 2026
- Session management cheat sheet, OWASP




