2026-01-10

From Zero to Sign-In: A 10-Line Flask Auth Pattern You Can Reuse Anywhere

Python, Flask, Security, Authentication · Dorian Sotpyrc

GitHub (ready-to-ship demo)

Clone the canonical repo (login, signup, forgot password, protected account page, SQLite user store, hashed passwords, safe redirects, session cookie posture): github.com/dorian-sotpyrc/flask-10-line-auth

Most Flask auth guides are either (1) too small to be safe, or (2) so “frameworky” you can’t tell what’s happening anymore. The fastest path to something you can ship is boring on purpose: put a single uid in the signed session cookie, and gate protected routes with one decorator. That’s the spine. Everything else stays explicit and auditable in your app.

A polished Flask sign-in UI representing a minimal session UID authentication baseline
The “smallest correct baseline” for Flask auth: session UID + a gate, wrapped in a clean, shippable UI.
TL;DR

The smallest correct auth baseline in Flask is not a framework. It’s a rule: store only a uid in session, and use a decorator to gate protected routes. That gives you predictable behavior, easy audits, and no hidden magic.

  • Session: store only uid (nothing sensitive)
  • Gate: @login_required redirects to login and preserves next
  • Ship-ready rails: safe next redirects + sensible session cookie posture (behind HTTPS)

UI preview (starter wireframe)

You don’t need a “design system overhaul” to ship auth. Start with a clean browser frame, one centered card, and four primitives: two inputs, one primary button, and two secondary links (forgot + signup). The repo keeps that structure consistent across all screens so the UX feels intentional without getting noisy.

Login
PLEX
Signup · Forgot password · Account (protected)
PLEX PLEX PLEX

The 10-line auth “spine” (session UID + gate)

Here’s the only code you need to understand to reason about the whole system. Everything else (signup flow, password hashing, storage, forgot-password UX) is implemented in the repo — but your auth posture lives or dies on these ten lines.

PYTHON
from functools import wraps
from flask import session, redirect, url_for, request

def login_user(uid): session["uid"] = uid
def logout_user(): session.pop("uid", None)
def current_uid(): return session.get("uid")

def login_required(view):
    @wraps(view)
    def wrapper(*args, **kwargs):
        if not current_uid():
            return redirect(url_for("login", next=request.full_path))
        return view(*args, **kwargs)
    return wrapper

Why this is “production-shaped” without sprawl

Flask’s session cookie is signed, which is perfect for a tiny auth baseline: you can trust integrity, but you still keep the payload minimal. Storing a uid (and only a uid) keeps you out of the danger zone: no secrets in the cookie, no huge user objects, no hidden state.

The repo makes this shippable: clean UI, login/signup/forgot flows, a protected account page, a simple user store, and secure sessions — while keeping the mental model simple: “session contains UID; gate checks UID; login sets UID; logout clears UID.”

Drop it into any Flask app

  1. Copy the spine
    Add the 10-line module to your project as plex_auth.py (or similar). Keep it dependency-free and easy to audit.
  2. Gate routes
    Put @login_required on anything protected. Let unauth users bounce to login with a preserved next path.
  3. Use the repo as your known-good template
    Clone the GitHub demo and lift the pieces you need (templates, routes, storage). Don’t reinvent auth behavior — keep it boring and consistent.

Related PLEX reading

References & further reading