Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Django middleware component that wraps the login_required decorator around all URL patterns be default, with exceptions. Can also require user to belong to a group ("admin" in this gist) or be adapted if using the Django admin app.
"""
Middleware component that wraps the login_required decorator around all URL patterns be default, with exceptions.
Define PUBLIC_URLS and ADMIN_URLS using regex in settings.py, where:
PUBLIC_URLS do not require user to be logged in.
ADMIN_URLS require user to be in admin group.
Source: http://stackoverflow.com/a/2164224/720054
"""
# settings.py
PUBLIC_URLS = (
r'/accounts/register/(.*)$',
r'/accounts/activate/(.*)$',
r'/accounts/password/reset/(.*)$',
r'/accounts/login/(.*)$',
r'/api/(.*)$',
)
ADMIN_URLS = (
r'/admin/(.*)$',
)
MIDDLEWARE_CLASSES = (
# Other middleware...
'middleware.LoginRequiredMiddleware',
)
# middleware.py
import re
from django.conf import settings
from django.contrib.auth.decorators import login_required, user_passes_test
class LoginRequiredMiddleware(object):
def __init__(self):
self.admin = tuple(re.compile(url) for url in settings.ADMIN_URLS)
self.public = tuple(re.compile(url) for url in settings.PUBLIC_URLS)
def process_view(self, request, view_func, view_args, view_kwargs):
# No need to process URLs if user is admin
if request.user.groups.filter(name="admin").exists():
return None
# Requests matching an admin URL pattern are returned wrapped with the user_passes_test decorator
for url in self.admin:
if url.match(request.path):
return user_passes_test(lambda u: u.groups.filter(name="admin").exists())(view_func)(request, *view_args, **view_kwargs)
# No need to process remaining URLs if user already logged in
if request.user.is_authenticated():
return None
# An exception match (public) should immediately return None
for url in self.public:
if url.match(request.path):
return None
# Require login for all non-matching requests
return login_required(view_func)(request, *view_args, **view_kwargs)
@gusarg81

This comment has been minimized.

Copy link

gusarg81 commented Aug 29, 2017

Hi, this does not work with django 1.10 or newer, because: https://docs.djangoproject.com/en/1.10/releases/1.10/#new-style-middleware.

Can you fix the example? I've tried but not luck, keeps redirecting me after login I've dont know why.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.