Plain is headed towards 1.0! Subscribe for development updates →

  1# plain.auth
  2
  3Add users to your app and define which views they can access.
  4
  5To log a user in, you'll want to pair this package with:
  6
  7- `plain-passwords`
  8- `plain-oauth`
  9- `plain-passkeys` (TBD)
 10- `plain-passlinks` (TBD)
 11
 12## Installation
 13
 14```python
 15# app/settings.py
 16INSTALLED_PACKAGES = [
 17    # ...
 18    "plain.auth",
 19    "plain.sessions",
 20    "plain.passwords",
 21]
 22
 23MIDDLEWARE = [
 24    "plain.sessions.middleware.SessionMiddleware",
 25    "plain.auth.middleware.AuthenticationMiddleware",
 26]
 27
 28AUTH_USER_MODEL = "users.User"
 29AUTH_LOGIN_URL = "login"
 30```
 31
 32Create your own user model (`plain create users`).
 33
 34```python
 35# app/users/models.py
 36from plain import models
 37from plain.passwords.models import PasswordField
 38
 39
 40class User(models.Model):
 41    email = models.EmailField()
 42    password = PasswordField()
 43    is_admin = models.BooleanField(default=False)
 44    created_at = models.DateTimeField(auto_now_add=True)
 45
 46    def __str__(self):
 47        return self.email
 48```
 49
 50Define your URL/view where users can log in.
 51
 52```python
 53# app/urls.py
 54from plain.auth.views import LoginView, LogoutView
 55from plain.urls import include, path
 56from plain.passwords.views import PasswordLoginView
 57
 58
 59class LoginView(PasswordLoginView):
 60    template_name = "login.html"
 61
 62
 63urlpatterns = [
 64    path("logout/", LogoutView, name="logout"),
 65    path("login/", LoginView, name="login"),
 66]
 67```
 68
 69## Checking if a user is logged in
 70
 71A `request.user` will either be `None` or point to an instance of a your `AUTH_USER_MODEL`.
 72
 73So in templates you can do:
 74
 75```html
 76{% if request.user %}
 77    <p>Hello, {{ request.user.email }}!</p>
 78{% else %}
 79    <p>You are not logged in.</p>
 80{% endif %}
 81```
 82
 83Or in Python:
 84
 85```python
 86if request.user:
 87    print(f"Hello, {request.user.email}!")
 88else:
 89    print("You are not logged in.")
 90```
 91
 92## Restricting views
 93
 94Use the `AuthViewMixin` to restrict views to logged in users, admin users, or custom logic.
 95
 96```python
 97from plain.auth.views import AuthViewMixin
 98from plain.exceptions import PermissionDenied
 99from plain.views import View
100
101
102class LoggedInView(AuthViewMixin, View):
103    login_required = True
104
105
106class AdminOnlyView(AuthViewMixin, View):
107    login_required = True
108    admin_required = True
109
110
111class CustomPermissionView(AuthViewMixin, View):
112    def check_auth(self):
113        super().check_auth()
114        if not self.request.user.is_special:
115            raise PermissionDenied("You're not special!")
116```