Restricting all the views to authenticated users in Django
Question:
I’m new to Django and I’m working on a project which has a login page as its index and a signup page. The rest of the pages all must be restricted to logged in users and if an unauthenticated user attempts to reach them, he/she must be redirected to the login page.
I see that @login_required
decorator would make a single view restricted to logged in users but is there a better way to make all the views restricted and only a few available to unauthenticated users?
Answers:
…is there a better way to make all the views restricted and only a few available to unauthenticated users?
This is a good use-case for class based views. Define a base class with the login handling, say LoginRequiredView
, and make any authenticated endpoints subclass this base, rather than using function-based views with decoration on each function.
The few views available to unauthenticated users will inherit from Django’s generic View
rather than the login required base.
Django actually provides a mixin class which you can use:
from django.contrib.auth.mixins import LoginRequiredMixin
class LoginRequiredView(LoginRequiredMixin, View):
login_url = '/login/'
redirect_field_name = 'redirect_to'
When a view uses this mixin, or subclasses a base with the mixin, requests by non-authenticated users will be redirected to the login page.
You can write a middleware:
from django.contrib.auth.decorators import login_required
def login_exempt(view):
view.login_exempt = True
return view
class LoginRequiredMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
return self.get_response(request)
def process_view(self, request, view_func, view_args, view_kwargs):
if getattr(view_func, 'login_exempt', False):
return
if request.user.is_authenticated:
return
# You probably want to exclude the login/logout views, etc.
return login_required(view_func)(request, *view_args, **view_kwargs)
You add the middleware to your MIDDLEWARES
list and decorate the views you don’t want authenticated with login_exempt
.
I’m new to Django and I’m working on a project which has a login page as its index and a signup page. The rest of the pages all must be restricted to logged in users and if an unauthenticated user attempts to reach them, he/she must be redirected to the login page.
I see that @login_required
decorator would make a single view restricted to logged in users but is there a better way to make all the views restricted and only a few available to unauthenticated users?
…is there a better way to make all the views restricted and only a few available to unauthenticated users?
This is a good use-case for class based views. Define a base class with the login handling, say LoginRequiredView
, and make any authenticated endpoints subclass this base, rather than using function-based views with decoration on each function.
The few views available to unauthenticated users will inherit from Django’s generic View
rather than the login required base.
Django actually provides a mixin class which you can use:
from django.contrib.auth.mixins import LoginRequiredMixin
class LoginRequiredView(LoginRequiredMixin, View):
login_url = '/login/'
redirect_field_name = 'redirect_to'
When a view uses this mixin, or subclasses a base with the mixin, requests by non-authenticated users will be redirected to the login page.
You can write a middleware:
from django.contrib.auth.decorators import login_required
def login_exempt(view):
view.login_exempt = True
return view
class LoginRequiredMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
return self.get_response(request)
def process_view(self, request, view_func, view_args, view_kwargs):
if getattr(view_func, 'login_exempt', False):
return
if request.user.is_authenticated:
return
# You probably want to exclude the login/logout views, etc.
return login_required(view_func)(request, *view_args, **view_kwargs)
You add the middleware to your MIDDLEWARES
list and decorate the views you don’t want authenticated with login_exempt
.