fixmyvibe.codes
<  Back to Blog

How to Add Authentication to a Vibe-Coded App the Right Way

6 min read By FixMyVibe Team
authentication security vibe-coding ai-tools

If we had to name the single riskiest thing AI coding tools get wrong, it wouldn’t be a broken button or a slow page. It would be authentication. We’ve reviewed dozens of apps built with Cursor, Bolt, Lovable and similar tools, and the pattern repeats: the login screen works perfectly. Type your password, click submit, land on the dashboard. Everything looks solved. Adding auth to an AI-built app is often the part founders trust the most, precisely because it’s the part that visibly appears to function. That trust is misplaced more often than we’d like.

Authentication vibe coding problems don’t usually show up as errors. They show up as silence. Nothing crashes. Nothing throws a warning in the console. The app just quietly lets the wrong person see the wrong data, and nobody notices until a user emails you asking why they can see someone else’s invoices.

What authentication actually has to do

Authentication has two separate jobs, and AI tools are decent at the first one and inconsistent at the second.

Job one is identity: confirming that the person typing the password is who they say they are. This is the part everyone tests, because it’s the part you can see. You log in, you get redirected, the UI updates. Cursor, Bolt and Lovable all handle this reasonably well because it’s a well-documented pattern with thousands of tutorials behind it.

Job two is authorisation: once someone is logged in, deciding what they’re actually allowed to do and see. Can user A fetch user B’s records by changing a number in the URL? Can a logged-out visitor still call the API that returns billing details? This is the part that requires the AI to reason about every single data-fetching path in your app and apply the same rule consistently. AI tools are far weaker at this, because it’s not one decision made once at login, it’s dozens of decisions that have to be made correctly every time data moves.

Most vibe-coded apps nail job one and fail job two in at least a few places. That gap is where the real damage happens.

The difference between login working and login being secure

A login screen “working” means: correct credentials get you in, wrong credentials get rejected, and the UI reflects your logged-in state. That’s a UX outcome. You can verify it in thirty seconds by trying to log in.

A login system being secure means something much wider: passwords are hashed properly, sessions can’t be hijacked or replayed, every protected page and every protected API endpoint independently checks who’s asking before returning anything, and there’s no path that lets someone skip the check entirely. That’s a systems property, and it can’t be verified by clicking around. You have to actually try to break it, or read the code that enforces it.

This is the trap. Founders test the thing that’s easy to test (does login work) and assume it proves the thing that’s hard to test (is the app actually locked). They’re not the same claim, and AI tools rarely tell you they’ve only delivered the first one. We’ve written before about how to review AI-generated code even if you’re not a developer, and auth is exactly the area where that skill pays off fastest.

Common AI auth failures

Three patterns come up again and again in the apps we get sent for review.

Client-side-only checks. The app hides a delete button, an admin panel, or a settings page based on the logged-in user’s role, and that’s treated as “protected.” But if the actual page or API endpoint behind that button doesn’t independently check the user’s role on the server, anyone who knows the URL or opens the browser’s network tab can reach it directly. Hiding something in the interface is not the same as protecting it. AI tools tend to solve the visible half of this problem (hide the button) and skip the invisible half (guard the endpoint), because the visible half is what gets rendered in the preview.

Unprotected APIs. Related but distinct: an endpoint that returns data with no authentication check attached to it at all. We’ve found API routes in generated codebases that will happily return a full user list, order history, or contact form submissions to anyone who requests the URL, logged in or not. Nobody built a wall there because nobody asked the AI to, and it didn’t think to ask you either. This is one of the recurring issues we cover in the 10 most common bugs in AI-generated code, and it’s usually the most serious one on that list.

Weak session handling. Sessions that never expire, tokens stored somewhere a script on the page can read them, or a “remember me” implementation that effectively means “stay logged in forever, on any device, until the heat death of the universe.” None of this breaks the demo. All of it becomes a real liability the moment your app has actual users with actual data worth stealing.

None of these are exotic mistakes. They’re the same handful of gaps we see over and over, for the same reason: the AI tends to reproduce whatever pattern is most common in its training data rather than reasoning from your app’s specific threat model. We go into why that keeps happening in why AI coding tools keep making the same mistakes.

Questions to ask about your own auth

You don’t need to read code to start checking this yourself. A few questions will tell you a lot.

If you log out, then paste a URL from inside your app directly into a new browser tab, does it show you data, or does it redirect you to log in? It should redirect.

If you open your browser’s developer tools, go to the Network tab, and click around your app while logged in as a normal user, do any requests return data that looks like it belongs to other people, or that an admin should see? It shouldn’t.

Do you know, off the top of your head, whether your passwords are stored hashed or in plain text? If you can’t answer that, ask whoever built the app, and ask them to show you, not just tell you.

Does your session ever expire, or once you’re logged in, are you logged in forever on that device? Indefinite sessions aren’t automatically wrong, but they should be a deliberate choice, not an accident of nobody setting an expiry.

Working through questions like these is also a good use of a moment before launch, and it overlaps heavily with the vibe coders’ pre-launch checklist we put together for exactly this reason.

When to bring in help

If you answered “I’m not sure” to more than one of those questions, that’s the signal, not a specific bug you’ve spotted. Auth is one of the few areas where “it seems fine” and “it is fine” can diverge completely, and the cost of that gap being wrong isn’t a bad review, it’s a data breach with your users’ names attached to it.

You don’t need to rebuild your whole app to fix this. Most of the time, auth issues in AI-generated codebases are contained: a handful of missing server-side checks, a session config that needs tightening, an API route that was never locked down. Someone who’s spent time in this kind of code can usually find and fix the real gaps in a day or two, without touching everything else that already works. Our broader guide on whether your AI-built app is secure walks through the wider picture beyond just login.


Not sure your login is actually locked? Get a free security check and we’ll tell you exactly where the gaps are.

Need help with your AI-generated code?

We fix bugs in vibe-coded apps and make them production-ready. Free code assessment — no commitment required.