Toggling an entire site to private/access denied

I needed an easy way to toggle the entire site to private/authenticated users only

The login required decorator would necessitate editing the code in multiple places constantly, so this is my middleware solution. What are more experienced Django users thoughts, and what could I do to improve, or perhaps use an entirely different method.

To toggle this on and off, a simple True or False is placed in settings.py after PRIVATE_SITE.

from django.conf import settings
from django.http import HttpResponse

def private_site_toggle(get_response):
“”"
Middleware to control access to a private site.
“”"

def middleware(request):
    """
    Check if the site is in private mode and deny access to unauthenticated users.
    """

    # Exclude specific URLs from the private mode check
    if should_exclude_url(request):
        return get_response(request)

    if settings.PRIVATE_SITE and not request.user.is_authenticated:
        return HttpResponse("Access Denied.", status=403)

    return get_response(request)

return middleware

def should_exclude_url(request):
“”"
Check if the current URL should be excluded from the private mode check.
“”"

excluded_urls = [
    "/admin/login/",
]

for url in excluded_urls:
    if request.path.startswith(url):
        return True

return False

There’s already a third-party package for that.

See django-login-required-middleware · PyPI

Note, if you want something easier to toggle without having to change / restart your app, you could also handle this in the nginx layer - see Show external folder html content in django - #2 by KenWhitesell. While this is referencing access to static or media files, nginx doesn’t really care what the resource is. You could use this to protect your application URLs as well.

1 Like

Thank you, great answer.