Login and Sessions

Sign people in with Django’s session auth and protect write actions.

Goal for this part

Sign neighbors in and out with Django’s session authentication. Protect every write. Show the signed-in name in the header.

Why session cookies, not JWTs in localStorage

Django stores a session key in an HttpOnly cookie. JavaScript cannot steal it with a casual XSS copy-paste. JWTs in localStorage are the default SPA pattern and a default theft target. Westloop is server-rendered; sessions are the correct tool. Same-site cookies plus CSRF is the pair that makes HTMX POSTs safe.

Walkthrough

Use Django’s built-in login view, or a thin wrapper if you want a Tailwind-styled template. Set the redirects once:

LOGIN_URL = "accounts:login"
LOGIN_REDIRECT_URL = "posts:feed"
LOGOUT_REDIRECT_URL = "posts:feed"
# accounts/urls.py
from django.contrib.auth import views as auth_views
from django.urls import path
from . import views

app_name = "accounts"
urlpatterns = [
    path("accounts/register/", views.register, name="register"),
    path("accounts/login/", auth_views.LoginView.as_view(template_name="accounts/login.html"), name="login"),
    path("accounts/logout/", auth_views.LogoutView.as_view(), name="logout"),
]

Logout must be a POST (Django 5 default). The header form is a button, not a GET link. Wrap future compose, like, follow, and comment views with @login_required.

How to run it and what you should see

Sign in as ada / password123. The header should show Ada’s display name and a Sign out button. Visit /accounts/login/ again while signed in and you should bounce to the feed. Sign out and the menu returns to Sign in / Join.

Common mistakes

A GET logout URL will 405. Missing CSRF on the login form is a 403. If login “works” but the next request is anonymous, you are on two different hosts (localhost vs 127.0.0.1) or SESSION_COOKIE_SECURE is true on HTTP.

Try this

Open DevTools → Application → Cookies. You should see sessionid and csrftoken, both HttpOnly or at least not readable as a JWT blob. Then try a wrong password and confirm the form error does not reveal whether the username exists.