Redirection to previous page after login using LoginRequiredMiddleware

Question:

I used to use next_param = request.POST.get('next') to redirect users to their previous page after they log in.

I however, decided to go fancier with my code and now force any unauthenticated user to login by using LoginRequiredMiddleware: users are automatically redirected to login page if not authenticated.

This allows me to avoid having to call a decorator for all views. Instead, specify the accessible views that don’t require the user to be logged in.

Small problem: my next_param = request.POST.get('next')doesnt work now for obvious reason: I cannot stick
?next={{ request.path|urlencode}} in the referring page since the redirection happens automatically and the user doesnt have to click anywhere.

What alternative do I have to redirect the user to the initial/previous page they landed on before being redirected automatically?

base.py

MIDDLEWARE = [
..
    'mysite.middleware.LoginRequiredMiddleware', 
]

middleware.py

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)
    

views.py

def login_user(request):
    if request.user.is_authenticated:
        return redirect('list-venues')
    if request.method == "POST":
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)
            next_param = request.POST.get('next')
            if next_param:    #<-- this is the bit that is not working anymore
                url= next_param
            else:
                url = reverse('list-venues')
            return redirect(url)
        else:
            messages.success(request,("There was an error, try again!"))
            return redirect('login_user')
    else:
        return render(request,'main/registration/login_user.html',{})
Asked By: PhilM

||

Answers:

You could place it in a session variable

In your middleware

   request.session['next_param'] = path
   return redirect(settings.LOGIN_URL)

Then in your login page

        ... 
        if user is not None:
            login(request, user)
            #next_param = request.POST.get('next')
            url= request.session.get('next_param', reverse('list_venues'))
            return redirect(url)
Answered By: SamSparx