The login screen that is not a login

  • September 5, 2026
  • Abhinav Chaudhary

A login screen is not authentication. Authentication is the server verifying identity on every request. AI coding tools generate the screen reliably and the server-side enforcement rarely, which produces apps where the interface hides things that the data layer will still hand over to anyone who asks.

Part of the guide to shipping an app built with an AI coding tool.

What the tools actually generate

A sign-up form, a sign-in form, a session, and interface logic that shows or hides things based on who is signed in. All of that is real and all of it works.

What is usually missing is the other half: the server refusing to send data to someone who should not have it. The interface stops showing the admin panel. The endpoint behind the admin panel keeps answering.

The two tests

Both take under a minute and neither needs any technical knowledge.

  1. Log out. Copy a URL that only works when you are logged in. Paste it into a private browsing window. If the page loads, your routes are not protected on the server.
  2. Sign up as a second user. Find a URL containing an ID — an order, a document, a profile. Change the ID to one belonging to your first account. If you can see it, your permissions exist only in the interface.

If either test lets you through, the login screen is decoration. That is not a criticism of your app; it is the single most common gap in this category of software.

Why roles in the browser do not work

A common pattern: the app stores something like isAdmin alongside the session and shows the admin area when it is true. It works, it looks correct, and it is not security.

That value lives in the visitor's own browser. Anyone can open developer tools and change it. The admin screens appear. Whether they are useful depends entirely on whether the server also checks — and if the server checked, hiding the screens would not have been necessary in the first place.

The rule: anything the browser can change is a display preference, not a permission.

What real enforcement looks like

  • The server checks the session on every request that returns private data, not once at login.
  • Roles are read from the database when needed, not carried in the browser.
  • The database has its own access rules, so even a request that bypasses your app entirely gets nothing.
  • Logging out invalidates the session rather than only clearing the screen.

Three layers, each independent. The interface is the convenience layer; it is fine for it to hide things, as long as it is not the only thing doing so.

How hard is this to fix?

Usually less work than people fear. The session handling is already there and already correct — it is the checks that are missing, and adding them is mechanical once you know which routes and which tables need them.

The exception is when ownership was never modelled in the data at all. If there is no column recording who a record belongs to, there is nothing for a rule to check, and that has to be fixed before any permission work can start.

Want someone to look at yours?

Send us the repo or the live URL. You get a written list of what is broken, what each fix costs and what can wait — back within 24 hours, and yours to keep either way.

Get a $99 audit