CodingIdeas.ai
← Browse All Ideas

Build Guide

How to Build a Login System

Building auth from scratch in 2026 is optional — but understanding what happens under the hood is not, because every security incident traces back to an auth mistake.

Intermediate1–3 days

Authentication is the first thing every SaaS needs. Build it yourself once to understand sessions, JWTs, OAuth flows, and password hashing — then use a managed service in production.

Data model

The core tables you'll need before writing any UI.

Userid, email, password_hash, email_verified, role (user/admin), created_at
Sessionid (random token), user_id, expires_at, created_at, ip, user_agent
PasswordResetTokentoken (random), user_id, expires_at (1 hour), used_at
OAuthAccountprovider (google/github), provider_user_id, user_id, access_token, refresh_token

Build order

The sequence that minimises rewrites — build in this order.

1

Password hashing and sign-up

Hash passwords with bcrypt (cost factor 12). Never store plain text. On sign-up: hash the password, insert the user, send a verification email with a signed token. Reject login until email is verified.

2

Session-based login

On login: verify email + bcrypt.compare(password, hash). If correct, generate a random session token, store it in the sessions table, and set it as an HttpOnly Secure cookie. Check this cookie on every protected request.

3

Middleware auth guard

Create a middleware function that reads the session cookie, looks up the session in the DB, checks it hasn't expired, and attaches the user to the request. Return 401 if missing or expired.

4

Password reset flow

POST /auth/forgot-password: find user by email, generate a random token, store in password_reset_tokens with 1-hour expiry, send email with reset link. POST /auth/reset-password: verify token not expired, hash new password, delete the token.

5

Google OAuth

Register an OAuth app in Google Cloud Console. Implement the OAuth2 flow: redirect to Google's auth URL → Google redirects back with a code → exchange code for tokens → fetch user profile → find or create your User row → create session.

6

Role-based access control

Add a role field to users (user / admin). In middleware, check role for admin-only routes. Create a withRole(role) higher-order function that wraps route handlers and rejects insufficient roles with 403.

7

Rate limiting

Limit /auth/login to 5 attempts per IP per 15 minutes using an in-memory counter (or Redis for multi-server). After 5 failures, return 429 Too Many Requests. Reset the counter on successful login.

Build it with AI — Architect Prompt

Paste this into Claude, Cursor, Windsurf, or any AI coding tool. It includes the full context of this guide — data model, build order, and pitfalls — so the AI starts with everything it needs.

ClaudeCursorWindsurfCopilotGemini
architect-prompt.txt
<context>
App: Login System
Difficulty: Intermediate
Estimated build time: 1–3 days

Data model:
  User: id, email, password_hash, email_verified, role (user/admin), created_at
  Session: id (random token), user_id, expires_at, created_at, ip, user_agent
  PasswordResetToken: token (random), user_id, expires_at (1 hour), used_at
  OAuthAccount: provider (google/github), provider_user_id, user_id, access_token, refresh_token

Recommended build order:
  1. Password hashing and sign-up — Hash passwords with bcrypt (cost factor 12). Never store plain text. On sign-up: hash the password, insert the user, send a verification email with a signed token. Reject login until email is verified.
  2. Session-based login — On login: verify email + bcrypt.compare(password, hash). If correct, generate a random session token, store it in the sessions table, and set it as an HttpOnly Secure cookie. Check this cookie on every protected request.
  3. Middleware auth guard — Create a middleware function that reads the session cookie, looks up the session in the DB, checks it hasn't expired, and attaches the user to the request. Return 401 if missing or expired.
  4. Password reset flow — POST /auth/forgot-password: find user by email, generate a random token, store in password_reset_tokens with 1-hour expiry, send email with reset link. POST /auth/reset-password: verify token not expired, hash new password, delete the token.
  5. Google OAuth — Register an OAuth app in Google Cloud Console. Implement the OAuth2 flow: redirect to Google's auth URL → Google redirects back with a code → exchange code for tokens → fetch user profile → find or create your User row → create session.
  6. Role-based access control — Add a role field to users (user / admin). In middleware, check role for admin-only routes. Create a withRole(role) higher-order function that wraps route handlers and rejects insufficient roles with 403.
  7. Rate limiting — Limit /auth/login to 5 attempts per IP per 15 minutes using an in-memory counter (or Redis for multi-server). After 5 failures, return 429 Too Many Requests. Reset the counter on successful login.

Known pitfalls to avoid:
  - Using JWT for sessions without a revocation mechanism — if you store sessions as stateless JWTs, you can't log a user out on the server side (a stolen token stays valid until expiry). Use server-side sessions stored in a database.
  - Storing passwords with MD5 or SHA-1 — these are not password hashing algorithms. Use bcrypt, scrypt, or argon2. They're designed to be slow, which is exactly what you want for password hashing.
  - Exposing the session token in the URL — always use HttpOnly cookies, never URL params or localStorage. localStorage is accessible to JavaScript (and thus XSS attacks).

Tech stack (intermediate): Supabase Auth + Next.js — open source, self-hostable, Postgres-native
</context>

<role>
You are a Senior Full-Stack Engineer and product architect who has shipped production Login Systems before. You know exactly where developers get stuck and how to structure the project to avoid rewrites.
</role>

<task id="step-1-clarify">
Before writing any code or spec, ask me 3–5 clarifying questions that will meaningfully change the architecture. Focus on: scale expectations, auth requirements, platform (web / mobile / both), must-have vs nice-to-have features for the MVP, and any hard constraints (budget, deadline, existing infrastructure).

<example>
BAD: "What tech stack do you want to use?" — too broad, doesn't change architecture decisions.
GOOD: "Do you need real-time sync across devices, or is single-device with periodic refresh acceptable? This decides whether we use WebSockets or simple REST polling and significantly affects infrastructure complexity."
</example>
</task>

<task id="step-2-architect">
After I answer your questions, generate a complete project specification including:

1. Final tech stack with version numbers
2. Full file and folder structure
3. Complete database schema — every table, column, type, index, and foreign key
4. All API routes with request/response shapes and auth requirements
5. Component tree with TypeScript props interfaces
6. Auth and authorisation flow (who can do what)
7. Step-by-step implementation plan in the exact build order from <context> above
8. All environment variables with descriptions

<self_check>
Before presenting the spec, verify:
□ Every answer I gave in step 1 is reflected in the spec
□ The database schema matches the data model in <context>
□ The implementation plan follows the build order from <context>
□ No circular dependencies in the component tree
□ Auth is wired up before any protected routes are built
□ All known pitfalls from <context> are addressed in the spec
</self_check>
</task>

<task id="step-2.5-agents-md">
Generate an AGENTS.md file at the project root. This file is read automatically by Claude Code, Cursor, Windsurf, Sourcegraph Cody, and all major AI coding tools at the start of every session.

Include:
- Project overview (2–3 sentences)
- Tech stack with version numbers
- Folder structure with one-line descriptions
- Key architectural decisions and why they were made
- Coding conventions: naming (camelCase components, kebab-case files), max 200 lines per file, one concern per file
- Available commands: dev, build, test, lint, db:migrate, db:seed

Note in the file: "Cursor users can symlink .cursorrules → AGENTS.md. Claude Code users can symlink CLAUDE.md → AGENTS.md."
</task>

<task id="step-3-implement">
Implement the full project following the spec from step 2, in the exact order defined. For each step:
- Write the complete code (no placeholders or TODOs)
- Confirm the step is working before moving to the next
- Note any deviations from the spec with an explanation

<constraints>
- Max 200 lines per file. WHY: every file must fit in one AI context window for easy review and editing.
- One concern per file. WHY: mixing auth logic into API routes makes it impossible to reuse — extract to lib/auth.ts.
- TypeScript strict mode, no `any` types. WHY: catches data shape mismatches at compile time, not in production at 2am.
- All database queries in server components or API routes only. WHY: keeps credentials server-side, prevents accidental client-side exposure.
- All environment variables documented in .env.example. WHY: the next developer (or your future self) should be able to set up the project in under 5 minutes.
- Comment every non-obvious decision. WHY: AI tools read your comments to understand intent — without them, the next edit will break the pattern you established.
</constraints>
</task>

How to use this prompt

  1. 1.Copy the prompt above
  2. 2.Open Claude, Cursor (Cmd+L), or Windsurf
  3. 3.Paste the prompt and send — the AI will ask 3–5 clarifying questions
  4. 4.Answer the questions, then it generates your full project spec
  5. 5.Continue in the same session to implement step by step

Common mistakes

What trips up most developers building this for the first time.

⚠️

Using JWT for sessions without a revocation mechanism — if you store sessions as stateless JWTs, you can't log a user out on the server side (a stolen token stays valid until expiry). Use server-side sessions stored in a database.

⚠️

Storing passwords with MD5 or SHA-1 — these are not password hashing algorithms. Use bcrypt, scrypt, or argon2. They're designed to be slow, which is exactly what you want for password hashing.

⚠️

Exposing the session token in the URL — always use HttpOnly cookies, never URL params or localStorage. localStorage is accessible to JavaScript (and thus XSS attacks).

Recommended tech stack

Pick the level that matches your experience.

Beginner

Clerk — 10 lines of code, full auth system with UI. Use this in production.

Intermediate

Supabase Auth + Next.js — open source, self-hostable, Postgres-native

Advanced

Auth.js (NextAuth) + Prisma + your own DB — full control, more responsibility

Take it further — related ideas

Each comes with revenue math, a full build guide, and a prompt to paste into Claude or Cursor.

9 ideas in the archive

Ship in:
beginnerBusiness Automation

ContractPulse - Vendor Renewal and Health Monitor for Bootstrapped SaaS Teams

Small SaaS teams routinely lose money on zombie vendor contracts because no one owns the renewal calendar. ContractPulse ingests your vendor invoices and emails, surfaces upcoming renewals, flags price drift, and sends Slack alerts 30 days out. It's the CFO dashboard you couldn't afford to hire.

Time to ship2 weeks
DemandHigh
Revenue7/10
AI quality score6/10
View Details →
intermediateNLP & Text AI

IntentShift - NLP Exit Intent Classifier for SaaS Cancellation Flows

Most SaaS cancellation surveys are graveyards of checkbox data nobody reads. IntentShift uses NLP to classify open-text cancellation reasons into actionable churn drivers with confidence scores, then triggers the right retention playbook automatically.

Time to ship2 weeks
DemandHigh
Revenue8/10
AI quality score7/10
View Details →
beginnerMarketing Automation

WaitlistWarm - Pre-Launch Email Sequence Builder That Converts Waitlist Signups Into Day-One Paying Customers

You build a waitlist landing page, collect 400 emails, launch, and 3 people buy. WaitlistWarm builds and sends a 6-email pre-launch nurture sequence that educates, qualifies, and pre-sells your waitlist so that by launch day they are already reaching for their credit card. No Mailchimp template hell, no copywriting degree required.

Time to ship1 week
DemandVery High
Revenue7/10
AI quality score6/10
View Details →
intermediateNLP & Text AI

ClaimParse - NLP Entity Extractor That Turns Dense Insurance Policy PDFs Into Structured Data

Insurance policy PDFs are written by lawyers for lawyers, but indie SaaS founders and insurtech startups need structured data from them right now. ClaimParse is a fine-tuned NER pipeline that extracts coverage limits, exclusions, deductibles, and effective dates from any uploaded insurance document and returns clean JSON. No more manual copy-paste into spreadsheets.

Time to ship3 weeks
DemandHigh
Revenue7/10
AI quality score7/10
View Details →
intermediateSaaS

ShiftFill - Self-Service Shift Swap Marketplace for Hourly Retail and Hospitality Teams

Shift managers at retail and restaurant chains spend 2 hours every Sunday texting staff to fill open shifts because their scheduling software has no self-service swap layer. ShiftFill is a mobile-first marketplace where employees post and claim open shifts in real time with manager approval in one tap.

Time to ship3 weeks
DemandVery High
Revenue8/10
AI quality score7/10
View Details →
beginnerSaaS

EORTrack - Remote Job Board for EOR-Sponsored Global Hiring

Remote job seekers waste hours crawling LinkedIn for companies that actually hire internationally via Employer of Record providers. EORTrack scrapes and aggregates EOR-friendly job listings with country eligibility tags, timezone filters, and EOR provider badges so you know before you apply.

Time to ship2 weeks
DemandVery High
Revenue8/10
AI quality score6/10
View Details →
beginnerSaaS

BookSlot - Freelancer-First Scheduling With Built-In Payments and Session Types

Calendly was built for sales teams, not solopreneurs charging $200/hour for consulting sessions. BookSlot is a scheduling tool where paid sessions, custom meeting types, and instant rescheduling are table stakes — not $20/month add-ons.

Time to ship2 weeks
DemandVery High
Revenue7/10
AI quality score6/10
View Details →
beginnerSaaS

IdeaScope - Instant Startup Idea Scorecard Without the Spreadsheet Hell

Founders waste hours manually Googling competitors, estimating TAMs, and arguing with their notes app about whether an idea is worth building. IdeaScope takes your raw idea and returns a scored validation card in 90 seconds: TAM estimate, competition density, suggested MVP stack, and a go/no-go signal. Stop journaling, start shipping.

Time to ship1 week
DemandVery High
Revenue8/10
AI quality score8/10
View Details →
intermediateAI Agents & RAG

DriftWatch - RAG-Powered Knowledge Base Staleness Detector for SaaS Docs Teams

Your help center says the button is blue. It turned orange in the last deploy. DriftWatch runs a nightly RAG agent that compares your live product UI screenshots against your documentation, surfaces every stale paragraph, and emails a diff report to your team.

Time to ship3 weeks
DemandHigh
Revenue7/10
AI quality score9/10
View Details →