Vibe Coding Accounts

Adding User Accounts to Your Vibe Coded App

Your app works as a single-player toy, and now you want people to sign up and save their own data. Login looks like the easiest feature to ask AI for — a form, a button, a "Welcome back" message — but it's also the feature where a shortcut fails badly: a leaked password, an account anyone can log into, or a "private" page that isn't actually private. This guide covers the safe way to add accounts as a vibe coder: why you should never let AI build your own password system, the exact prompt to ask for, and how to check that a page is really protected instead of just hidden.

Last reviewed: Jul 18 2026

A glowing key-shaped token moving through a corridor of layered checkpoint gates, with one gate lit in warm amber where the token is verified before passing through.
A page is only protected once the check happens before the data is served — not after the visitor lands on it.

Why Login Deserves Extra Scrutiny

A login form is one of the easiest things to ask AI for, and one of the easiest to get wrong in a way you won't notice until it's a problem. AI can produce a form, a "sign up" button, and a page that says "Welcome back, [name]" — and it will look finished. What's easy to miss is whether passwords are actually stored safely, whether a session can be forged, and whether a "protected" page is protected on the server or just hidden by the interface.

The good news is the same as with payments: you don't need to understand cryptography to do this safely. You need to avoid one common mistake — building your own password storage — and confirm one thing AI tools sometimes skip: that protected pages check the session on the server, not just in the browser.

Never Let Your App Store Raw Passwords

If an AI tool ever generates code that saves a password directly into your database — even briefly, even for testing — stop. A password should never exist in your database as plain, readable text; it should be run through a one-way hashing function before it's stored, and ideally you shouldn't be writing that code at all. The fix below avoids this entirely by letting a dedicated auth provider handle passwords for you.


The Safe Default: A Hosted Auth Provider

Just as hosted checkout delegates the hardest parts of payment handling, a hosted authentication provider delegates password storage, verification, sessions, and recovery. Depending on the provider, people may use a hosted screen, a pre-built component, or a form in your app that calls the provider's SDK. The important boundary is that your database and backend never store or process the password themselves; the provider receives it and your app works with the resulting session.

All three keep password storage entirely on the provider's side. Writing your own login system with a library like bcrypt is possible and sometimes appropriate for larger apps, but it's much more surface area to get wrong — start with a hosted provider unless you have a specific reason not to.


The Prompt to Ask For

Name the hosted provider explicitly so AI doesn't default to writing its own login form, and ask for protected-route handling in the same prompt so it isn't left as an afterthought:

Prompt

Add email/password sign-up and login to my app using [Supabase Auth / Clerk / Firebase Auth]. Do not write custom password hashing or storage — use the provider's built-in auth. Include: (1) sign-up and login forms that call the provider's SDK, (2) a way to check the current session on both the client and the server or provider-enforced data layer, (3) at least one protected page that redirects to login if there's no valid session, checked before the page's data loads, and (4) authorization rules that let each user read and change only their own records. List which configuration values are safe in browser code and which are backend secrets. Do not rely on hiding a key to protect data.

When the AI returns code, check for these three things before you consider it done:

  1. No password ever touches your own database or backend code — it should go straight from the login form to the provider's SDK.
  2. Protected pages check the session before rendering private data, not after — the next section explains why the order matters.
  3. Only client-safe configuration is used in browser code — such as a Supabase publishable key, Clerk publishable key, or Firebase web configuration. Admin, secret, and service-role keys stay in backend-only code.
  4. Every data operation has an ownership or permission rule — being logged in is not enough to let someone read or change another user's records.

Why Hiding a Link Isn't the Same as Protecting Data

It's tempting to "protect" a page by simply not linking to it unless someone is logged in, or by hiding a component with an if (loggedIn) check in the browser. Don't stop there: anyone can type the page's URL directly, and browser-side JavaScript can be inspected or bypassed entirely. Hiding a link changes what a logged-out user sees; it does nothing to stop them from requesting the page or its data directly. And checking only that someone is logged in still isn't enough: the app must also check that this particular user is allowed to access this particular record or action.

Check Identity and Permission Where the Data Lives

A page is actually protected when the system that fetches or returns private data verifies both a valid session and permission to access the requested record. That enforcement may live in your server or backend function, or in a provider-enforced data layer such as Supabase Row Level Security or Firebase Security Rules. The client-side redirect that sends a logged-out visitor back to the login page is useful, but it isn't the security boundary. The real boundary is the rule that runs before data is read, changed, or sent.

In practice: the protected route, API endpoint, or database rule verifies the user's session and compares their user ID or permission with the requested resource before allowing the operation. Test this with two accounts: create data as Account A, then try to read, edit, and delete it as Account B by changing the record ID or calling the data endpoint directly. Account B should be denied every time. A page that merely redirects logged-out users in the browser, with no matching check on the data request itself, isn't protected — it's decorated.

Prompt

Show me every place that reads or changes data for my protected page. Confirm each operation verifies the session and checks that the current user owns the requested record or has an explicit permission before it reads, updates, or deletes anything. If data is accessed directly from the browser, show the provider-enforced rules that make the same check. Also give me a two-account test that proves one user cannot access another user's data.


Password Reset and Email Verification

These two flows are easy to skip in a first pass, because the app "works" without them — right up until a real user forgets their password or signs up with a typo'd email. Both are standard features in every hosted auth provider; you're wiring them up, not building them from scratch.

Prompt

Add password reset and email verification using [provider]'s built-in flows. Unverified users should [be able to use the app with a banner asking them to verify / be blocked from [specific feature] until verified]. Show me where each email template and redirect URL is configured.


Test Users Before Real Ones

Keep development and production accounts separate so experiments and test users never touch real data. How you do this depends on the provider: Clerk supplies distinct development and production instances, while Supabase and Firebase projects are commonly separated by environment. Each environment gets its own configuration and backend secrets.


Pre-Launch Accounts Checklist

Related Guides

Adding Payments to Your Vibe Coded App

The natural next step once users can log in — hosted checkout, webhooks, and what to check before real money moves.

Growing Your Vibe Coded App

Adding features, handling real users, and keeping an eye on hosting and storage costs as your app grows.

Sanitizing Code and Data Before Sending to AI

What to scrub before pasting code or credentials into an AI conversation — including API keys.

Back to Home