User Authentication

Django's authentication system manages user accounts, logging in, and logging out — it verifies a username and password with authenticate(), starts a session with login(), ends it with logout(), and exposes the current user on every request as request.user.

Learn User Authentication in our free Django course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free Django course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

In this lesson you'll create users the safe way with hashed passwords, sign people in and out, check whether a visitor is authenticated, and wire up Django's ready-made login and registration tools so you don't have to build them by hand.

Django ships with a built-in User model that lives in django.contrib.auth.models . Each user has fields like username , email , password , is_active , and is_staff . You almost never write this model yourself — Django created it and its database table for you when you ran your first migration.

The single most important rule of authentication: never set the password field directly . Always create accounts with User.objects.create_user() , which hashes the password before saving it. Storing a raw password is a serious security bug.

Signing someone in is two steps. First authenticate() checks the credentials and returns the matching User (or None if they are wrong). Then login() takes that user and starts a session so they stay signed in. To sign someone out, call logout() .

On every request, Django gives you request.user . For a signed-in visitor it is their User object; for an anonymous visitor it is an AnonymousUser . Check request.user.is_authenticated to tell them apart.

You rarely need to write login logic by hand. Django provides LoginView and LogoutView , and including django.contrib.auth.urls in your URLconf wires up the whole login, logout, and password-reset flow.

For sign-up, the UserCreationForm gives you a complete, validated registration form. Render it in a view, and on a valid POST call form.save() to create the account.

In a template you can show different links depending on whether the visitor is signed in:

Fill in the blanks so the view verifies the credentials and then starts the session. One blank should be authenticate and one should be login .

❌ Storing the raw password instead of using create_user()

Setting user.password = "plain" stores an unusable, insecure string — login will never succeed and real passwords are exposed.

✅ Fix: use User.objects.create_user(...) or user.set_password("...") so the password is hashed.

❌ authenticate() returns None for bad credentials

A wrong username or password makes authenticate() return None , and passing None to login() raises an error.

✅ Fix: always check if user is not None: before calling login() .

❌ Forgetting to call login() after authenticate()

authenticate() only verifies — it does not start a session. Skip login() and the visitor is never actually signed in.

✅ Fix: after a successful authenticate() , call login(request, user) to begin the session.

Build a miniature auth system: register a user with a hashed password, then log them in only when the credentials match.

Lesson 17 complete — you can sign users in and out!

You now know how the User model stores hashed passwords, how to create accounts with create_user(), how authenticate() and login() work together, how to sign out with logout(), how to check request.user.is_authenticated, and how Django's built-in auth views and UserCreationForm save you from writing it all yourself.

🚀 Up next: Permissions & Decorators — control who is allowed to do what with permissions and the @login_required decorator.

Practice quiz

What does authenticate() return on success?

  • True
  • The matching User object
  • A session id
  • None

Answer: The matching User object. authenticate() returns the User if the credentials match, or None if they do not.

What does login() do after authenticate()?

  • Hashes the password
  • Returns the User
  • Starts a session for the authenticated user
  • Creates the account

Answer: Starts a session for the authenticated user. login(request, user) starts a session so the user stays signed in across requests.

Which is the safe way to create a user with a hashed password?

  • User.objects.create_user(...)
  • User(password='plain').save()
  • user.password = 'plain'
  • User.objects.raw_create(...)

Answer: User.objects.create_user(...). create_user() hashes the password before saving; never assign the password field directly.

How do you check whether the current visitor is signed in?

  • request.is_logged_in
  • request.session.active
  • request.has_user
  • request.user.is_authenticated

Answer: request.user.is_authenticated. request.user.is_authenticated is True for signed-in users and False for AnonymousUser.

Does Django store raw passwords?

  • Yes, in plain text
  • No, it stores a salted hash (PBKDF2 by default)
  • Only the first 8 characters
  • Yes, but encrypted reversibly

Answer: No, it stores a salted hash (PBKDF2 by default). Django stores only a salted hash like pbkdf2_sha256$..., never the raw password.

What ends the current user's session?

  • logout(request)
  • request.user.delete()
  • authenticate(None)
  • login(request, None)

Answer: logout(request). logout(request) clears the session and signs the user out.

Including which URLconf wires up LoginView, LogoutView, and password reset?

  • django.contrib.admin.urls
  • django.urls.auth
  • django.contrib.auth.urls
  • django.auth.views

Answer: django.contrib.auth.urls. include('django.contrib.auth.urls') provides the ready-made auth views.

Which form gives you a complete, validated registration form?

  • LoginForm
  • AuthForm
  • SignupModel
  • UserCreationForm

Answer: UserCreationForm. UserCreationForm validates the data and saves a new user with a hashed password.

What is request.user for an anonymous visitor?

  • None
  • An AnonymousUser instance
  • An empty string
  • A 403 error

Answer: An AnonymousUser instance. Anonymous visitors get an AnonymousUser, whose is_authenticated is False.

What happens if you pass None to login()?

  • It raises an error
  • It logs in as admin
  • It silently succeeds
  • It returns False

Answer: It raises an error. Always check 'if user is not None' before calling login(); passing None raises an error.