Django, redirect all non-authenticated users to landing page

Question:

I have a django website with many urls and views. Now I have asked to redirect all non-authenticated users to a certain landing page. So, all views must check if user.is_authenticated() and return to a new set of landing pages.

Can it be done in a pretty way, instead of messing with my views.py/urls.py that much?

Asked By: xpanta

||

Answers:

see the docs for login required decorator

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
    ...

another option is to add it to your urls.py patterns, see this answer

urlpatterns = patterns('',
    (r'^foo/$', login_required(direct_to_template), {'template': 'foo_index.html'}),
)
Answered By: Guy Gavriely

You can use Middleware.

Something like this will check user auth every request:

class AuthRequiredMiddleware(object):
    def process_request(self, request):
        if not request.user.is_authenticated():
            return HttpResponseRedirect(reverse('landing_page')) # or http response
        return None

Docs: process_request

Also, don’t forget to enable it in settings.py

MIDDLEWARE_CLASSES = (
    ...
    'path.to.your.AuthRequiredMiddleware',
)
Answered By: Dmit3Y

This can be done with middleware.

I’ve found a really nifty djangosnippet that does exactly what you are asking for. You can find it here, and it looks like:

from django.http import HttpResponseRedirect
from django.conf import settings
from re import compile

EXEMPT_URLS = [compile(settings.LOGIN_URL.lstrip('/'))]
if hasattr(settings, 'LOGIN_EXEMPT_URLS'):
    EXEMPT_URLS += [compile(expr) for expr in settings.LOGIN_EXEMPT_URLS]

class LoginRequiredMiddleware:
    """
    Middleware that requires a user to be authenticated to view any page other
    than LOGIN_URL. Exemptions to this requirement can optionally be specified
    in settings via a list of regular expressions in LOGIN_EXEMPT_URLS (which
    you can copy from your urls.py).

    Requires authentication middleware and template context processors to be
    loaded. You'll get an error if they aren't.
    """
    def process_request(self, request):

        assert hasattr(request, 'user'), "The Login Required middleware
 requires authentication middleware to be installed. Edit your
 MIDDLEWARE_CLASSES setting to insert
 'django.contrib.auth.middlware.AuthenticationMiddleware'. If that doesn't
 work, ensure your TEMPLATE_CONTEXT_PROCESSORS setting includes
 'django.core.context_processors.auth'."

        if not request.user.is_authenticated():
            path = request.path_info.lstrip('/')
            if not any(m.match(path) for m in EXEMPT_URLS):
                return HttpResponseRedirect(settings.LOGIN_URL)

All you have to do is to save the file as middleware.py and include the class in you’re settings.py, i.e.

MIDDLEWARE_CLASSES += ('projectname.common.middleware.RequireLoginMiddleware',)

You can also define a LOGIN_URL in settings.py, so that you’ll be redirected to your custom login page. The default LOGIN_URL is '/accounts/login/'.

Answered By: Martin Hallén

As of Django 1.10, the custom middleware classes must implement the new style syntax. You can use the following class to verify that the user is logged in while trying to access any views.

from django.shortcuts import HttpResponseRedirect


class AuthRequiredMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = self.get_response(request)
        if not request.user.is_authenticated: # in Django > 3 this is a boolean
            return HttpResponseRedirect('login')
        
        # Code to be executed for each request/response after
        # the view is called.

        return response
Answered By: IVI

There is a simpler way to do this, just add the “login_url” parameter to @login_required and if the user is not login he will be redirected to the login page. You can find it here

from django.contrib.auth.decorators import login_required

@login_required(login_url='/accounts/login/')
def my_view(request):
    ...
Answered By: AriG

Maybe too late but in django 1.9+ it’s too easy.
Django introduced Login Required mixin for generic classes and this a great example
here by William S. Vincent

simply in your view add LoginRequiredMixin as parent class

from django.contrib.auth.mixins import LoginRequiredMixin

class BlogUpdateView(LoginRequiredMixin, UpdateView):
model = Post
template_name = 'post_edit.html'
fields = ['title', 'body']

Also you can use login_required decorator for method request

Answered By: Alireza Saremi
from django.contrib.auth.decorators import login_required

@login_required(login_url='/login/')

def home(request):
    return render(request, "home.html")

It’s showing like this: http://127.0.0.1:1235/login/?next=/home/

Answered By: Khairul2kha

You can avoid specifying login_url by setting LOGIN_URL.

Therefore, in settings.py add:

LOGIN_URL = '<some_url>'

And in your views.py annotate relevant functions with only @login_required:

@login_required
def some_view_function(request):

If you need to redirect within a view function, you can do so with:

return redirect_to_login(request.get_full_path())
Answered By: Rok StrniĊĦa

I’m using class based views and I couldn’t get any of these solutions to work for what I needed so I’ll post my working solution here.

class ManagementPageView(TemplateView):

    # Make a dispatch method to handle authentication
    def dispatch(self, *args, **kwargs):

        # Check if user is authenticated 
        if not self.request.user.is_authenticated:

            # Redirect them to the home page if not 
            return redirect('home')
            
        # Render the template if they are 
        return render(self.request, 'management.html')
Answered By: Casivio
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.