Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restricting all the views to authenticated users in Django

Tags:

python

django

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?

like image 710
Mohammed Farahmand Avatar asked Jan 23 '18 17:01

Mohammed Farahmand


People also ask

How do I restrict users in Django?

Django admin allows access to users marked as is_staff=True . To disable a user from being able to access the admin, you should set is_staff=False . This holds true even if the user is a superuser. is_superuser=True .

Does Django have view permissions?

The Django admin site uses permissions as follows: Access to view objects is limited to users with the “view” or “change” permission for that type of object. Access to view the “add” form and add an object is limited to users with the “add” permission for that type of object.


2 Answers

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.

like image 98
Blender Avatar answered Oct 29 '22 14:10

Blender


...is there a better way to make all the views restricted and only a few available to unauthenticated users?

Yes. It's time for you to learn class based views. Define a base class which requires login, and make any authenticated endpoints inherit this base class, rather than using function-based views with decoration on each function.

A popular design pattern in the implementation is to use a mixin class:

from django.contrib.auth.mixins import LoginRequiredMixin

class MyView(LoginRequiredMixin, View):
    login_url = '/login/'
    redirect_field_name = 'redirect_to'

If a view uses this mixin, all requests by non-authenticated users will be redirected to the login page.

like image 42
wim Avatar answered Oct 29 '22 15:10

wim