Skip to main content

plain.auth

Add users to your app and decide what they can access.

Overview

The plain.auth package handles user authentication and authorization for Plain applications. You can check if a user is logged in like this:

from plain.auth import get_request_user

user = get_request_user(request)
if user:
    print(f"Hello, {user.email}!")
else:
    print("You are not logged in.")

You can restrict a view to logged-in users using AuthViewMixin:

from plain.auth.views import AuthViewMixin
from plain.views import View


class ProfileView(AuthViewMixin, View):
    login_required = True

    def get(self):
        return f"Welcome, {self.user.email}!"

Authentication setup

Settings configuration

Configure your authentication settings in app/settings.py:

INSTALLED_PACKAGES = [
    # ...
    "plain.auth",
    "plain.sessions",
    "plain.passwords",  # Or another auth method
    "app.users",
]

MIDDLEWARE = [
    "plain.sessions.middleware.SessionMiddleware",
    "plain.auth.middleware.AuthMiddleware",
]

AUTH_LOGIN_URL = "login"

Creating a user model

plain.auth expects your project's User class at app.users.models.User — a fixed convention, not a configurable setting. The package label (users), module (models.py), and class name (User) are all required.

You can create one with plain create users or manually:

# app/users/models.py
from datetime import datetime

from plain import postgres
from plain.postgres import Field, types
from plain.passwords.models import PasswordField


@postgres.register_model
class User(postgres.Model):
    email: Field[str] = types.EmailField()
    password: Field[str] = PasswordField()
    is_admin: Field[bool] = types.BooleanField(default=False)
    created_at: Field[datetime] = types.DateTimeField(create_now=True)

    def __str__(self):
        return self.email

Login views

To log users in, you need to pair this package with an authentication method:

Here's an example with password authentication:

# app/urls.py
from plain.auth.views import LogoutView
from plain.urls import path
from plain.passwords.views import PasswordLoginView


class LoginView(PasswordLoginView):
    template_name = "login.html"


urlpatterns = [
    path("logout/", LogoutView, name="logout"),
    path("login/", LoginView, name="login"),
]

Checking if a user is logged in

In templates, you can use the get_current_user() function:

{% if get_current_user() %}
    <p>Hello, {{ get_current_user().email }}!</p>
{% else %}
    <p>You are not logged in.</p>
{% endif %}

In Python code, use get_request_user():

from plain.auth import get_request_user

user = get_request_user(request)
if user:
    print(f"Hello, {user.email}!")
else:
    print("You are not logged in.")

Restricting views

You can use AuthViewMixin to restrict views to logged-in users, admin users, or custom logic:

from plain.auth.views import AuthViewMixin
from plain.http import ForbiddenError403
from plain.views import View


class LoggedInView(AuthViewMixin, View):
    login_required = True


class AdminOnlyView(AuthViewMixin, View):
    login_required = True
    admin_required = True


class CustomPermissionView(AuthViewMixin, View):
    def check_auth(self):
        super().check_auth()
        if not self.user.is_special:
            raise ForbiddenError403("You're not special!")

The AuthViewMixin provides:

  • login_required - Requires a logged-in user
  • admin_required - Requires user.is_admin to be True
  • check_auth() - Override for custom authorization logic

Testing with authenticated users

When writing tests, you can use login_client() to simulate an authenticated user:

from plain.auth.test import login_client
from plain.test import Client

from app.users.models import User


def test_profile_view():
    user = User.objects.create(email="test@example.com")
    client = Client()
    login_client(client, user)

    response = client.get("/profile/")
    assert response.status_code == 200

You can also log out a test user with logout_client():

from plain.auth.test import login_client, logout_client

# ... after logging in
logout_client(client)

Settings

Setting Default Env var
AUTH_LOGIN_URL Required PLAIN_AUTH_LOGIN_URL
AUTH_USER_SESSION_HASH_FIELD "password" or "" PLAIN_AUTH_USER_SESSION_HASH_FIELD

See default_settings.py for more details.

FAQs

How do I log in a user programmatically?

You can use the login() function to log in a user:

from plain.auth.sessions import login

login(request, user)

How do I log out a user programmatically?

You can use the logout() function:

from plain.auth.sessions import logout

logout(request)

How do I invalidate sessions when a user changes their password?

By default, if you have plain.passwords installed, sessions are automatically invalidated when the password field changes. This is controlled by the AUTH_USER_SESSION_HASH_FIELD setting. You can change this to a different field name, or set it to an empty string to disable this feature.

How do I reference the User class?

Import it directly from app.users.models — the location is fixed:

from app.users.models import User

Installation

Install the plain.auth package from PyPI:

uv add plain.auth

Metadata

Release files for plain.auth 0.29.10

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for plain.auth 0.29.10
File Size Uploaded
plain_auth-0.29.10.tar.gz 18.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for plain.auth 0.29.10
File Interpreter ABI Platform
plain_auth-0.29.10-py3-none-any.whl Python 3 none any Details

Total release size: 38.6 kB

Release files / plain_auth-0.29.10.tar.gz

Download URL plain_auth-0.29.10.tar.gz
Size 18.0 kB
Tags Source
SHA-256 checksum
How to use checksums
2080a336d38eb15369aab8cdd61c7dbe099cd54ada0a038d2218b8fe1069df65
BLAKE2b-256 checksum
How to use checksums
9e3ebf587cc665baf8ae6b27ccc8d525020cd5c547b41ed1a24d21b269a014ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / plain_auth-0.29.10-py3-none-any.whl

Download URL plain_auth-0.29.10-py3-none-any.whl
Size 20.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0f91153f454eecb8f587ffc6b0cddf2d8b69a24a4ca30991d15e4fc207480db3
BLAKE2b-256 checksum
How to use checksums
94704f11bd1f5814c8433cd0e44e2e2850c553f0dea696fcf64efa92c13ea869
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.30.0

2 release files

This release

0.29.10 This release

2 release files

0.29.9

2 release files

0.29.7

2 release files

0.29.4

2 release files

0.29.3

2 release files

0.29.2

2 release files

0.29.1

2 release files

0.29.0

2 release files

0.28.0

2 release files

0.27.3

2 release files

0.27.2

2 release files

0.27.1

2 release files

0.25.4

2 release files

0.25.3

2 release files

0.25.1

2 release files

0.25.0

2 release files

0.24.0

2 release files

0.23.0

2 release files

0.22.0

2 release files

0.21.0

2 release files

0.20.7

2 release files

0.20.6

2 release files

0.20.5

2 release files

0.20.4

2 release files

0.19.0

2 release files

0.18.0

2 release files

0.17.0

2 release files

0.16.0

2 release files

0.15.0

2 release files

0.14.0

2 release files

0.13.0

2 release files

0.12.1

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

0.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page