pythondjangodjango-viewsdjango-middleware

Redirect non authenticated user to login page (for all views)


I am looking to redirect my user to login page, if they have not logged in.

I initally looked at the decorator @login_required(login_url='/accounts/login/').

But this is not ideal, for 2 reasons: first I want this to apply to all views. Also the decorator returns an error message when I try to login with allauth.

I am sure this is solvable, but I am looking for a solution that could apply to all views.

I found something using authmiddleware(doc: https://pypi.org/project/django-authmiddleware/). However the code doesn't not seem to be responsive, in the sense nothing is happening and the logs on the console don't seem to pick up anything.

Can someone see what I am doing wrong?

base.py

MIDDLEWARE = [

    'django.contrib.sessions.middleware.SessionMiddleware',

    'AuthMiddleware.middleware.AuthRequiredMiddleware', 
]
AUTH_SETTINGS = {

    "LOGIN_URL" : "login_user",
    "DEFAULT_REDIRECT_URL" : None,
    "REDIRECT_AFTER_LOGIN" : False,

}

views.py

from django.shortcuts import render, redirect, reverse
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth import authenticate, login, logout, get_user_model
from django.urls import reverse

def list_event(request): #ADDED FOLLOWING REQUEST IN COMMENTS
    event_list = Event.objects.all
    return render(request, 'main/list_event.html',{'event_list':event_list})

class AuthRequiredMiddleware(object):
    def process_request(self, request):
        if not request.user.is_authenticated():
            return HttpResponseRedirect(reverse('login_user'))
        return None 

Solution

  • Found an alternative solution and thought I would leave it there.

    I used a tutorial on youtube (https://www.youtube.com/watch?v=axsaC62UQOc) which, with a few changes (the video is old), works like a charm. Its about 3 videos 30 minutes very well explained.

    Here it goes:

    settings.py

    MIDDLEWARE = [
    
        '[yourappname].middleware.LoginRequiredMiddleware', 
    ]
    
    LOGIN_EXEMPT_URLS =( #<-- I am using allauth, so left some examples here)
        r'logout',
        r'register_user',
        r'accounts/google/login/',
        r'accounts/social/signup/',
        r'accounts/facebook/login/',
        
    )
    

    middleware.py (this files goes in your main app, by default "mysite")

    import re
    from django.conf import settings
    from django.shortcuts import redirect
    
    EXEMPT_URLS = [re.compile(settings.LOGIN_URL.lstrip('/'))]
    if hasattr(settings, 'LOGIN_EXEMPT_URLS'):
        EXEMPT_URLS += [re.compile(url) for url in settings.LOGIN_EXEMPT_URLS]
    
    class LoginRequiredMiddleware:
        pass
        def __init__(self, get_response):
            self.get_response = get_response
            
        def __call__ (self, request):
            response = self.get_response(request)
            return response
        
        def process_view(self, request, view_func, view_args, view_kwargs):
            assert hasattr(request,'user')
            path = request.path_info.lstrip('/')
            print(path)
            
            if not request.user.is_authenticated:
                if not any(url.match(path) for url in EXEMPT_URLS):
                    return redirect(settings.LOGIN_URL)