Skip to content

Instantly share code, notes, and snippets.

@mh-firouzjah
Last active August 21, 2022 08:24
Show Gist options
  • Save mh-firouzjah/d35828bfc5ca4c365a255b8eb97a98e2 to your computer and use it in GitHub Desktop.
Save mh-firouzjah/d35828bfc5ca4c365a255b8eb97a98e2 to your computer and use it in GitHub Desktop.
Django Login Required Middleware

Django Login Required Middleware

if you need users to be loged in first, before visiting your website, so it's easier to use a middleware to check if they're loged in or not. inorder to have such a middleware, use the following code:

# middleware.py
import re

from django.conf import settings
from django.contrib.auth.middleware import AuthenticationMiddleware
from django.shortcuts import redirect
from django.urls import NoReverseMatch, resolve, reverse

IGNORE_PATHS = [re.compile(settings.LOGIN_URL)]

IGNORE_PATHS += [
    re.compile(url) for url in getattr(settings, 'LOGIN_REQUIRED_IGNORE_PATHS', [])
]

IGNORE_VIEW_NAMES = [
    name for name in getattr(settings, 'LOGIN_REQUIRED_IGNORE_VIEW_NAMES', [])
]


class LoginRequiredMiddleware(AuthenticationMiddleware):
    """
    If LOGIN_REQUIRED is True, redirect all non-authenticated users to the login page.
    """
    def process_view(self, request, view_func, view_args, view_kwargs):
        path = request.path

        if not settings.LOGIN_REQUIRED or request.user.is_authenticated:
            return

        resolver = resolve(path)
        view_found = (True for name in IGNORE_VIEW_NAMES if name == resolver.view_name)

        path = path.split("?next=")[0]

        if not any(view_found) and not any(re.search(url, path) for url in IGNORE_PATHS):
            try:
                login_url = reverse(settings.LOGIN_URL)
            except NoReverseMatch:
                login_url = settings.LOGIN_URL
            return redirect(f'{login_url}?next={path}')

now add the middleware to settings.py middlewares list(or simply add the following code bellow default MIDDLEWARE), so django will use it:

# settings.py
# custom middlewares
MIDDLEWARE += [
    'apps.accounts.middleware.LoginRequiredMiddleware',
    ...
]
  • LOGIN_REQUIRED_IGNORE_PATHS urls list, e.g: /admin/login/ ignored by LoginRequiredMiddleware.
  • LOGIN_REQUIRED_IGNORE_VIEW_NAMES views name, e.g:admin:login ignored by LoginRequiredMiddleware.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment