This article explains how to redirect users back to the originally requested page after a successful login when using Django's @login_required decorator.
When an unauthenticated user tries to access a view protected by @login_required, they are redirected to the login page. The challenge is ensuring that after successful login, the user returns to the page they originally wanted to visit.
A common issue is that the next parameter from the URL is not available in the POST request after login. To solve this, we need to pass the next value from the GET request to a hidden field in the login form, so it can be retrieved during the POST request.
Implementation
URL Configuration (urls.py)
urlpatterns = [
url(r'^01-temp/$', views.temp_views),
url(r'^form/$', views.fun, name='form'),
url(r'^loginv/', views.loginl, name="login"),
url(r'^createuser/$', views.create_user),
url(r'^auth/$', views.auth),
url(r'^logoutv/$', views.logoutl),
]
View Logic (views.py)
def loginl(request):
if request.method == "GET":
nexturl = request.GET.get("next", "")
print(request.user.is_authenticated)
if request.user.is_authenticated:
if nexturl:
return redirect(nexturl)
else:
return HttpResponse("Login successful")
else:
return render(request, 'login.html', {'nexturl': nexturl})
elif request.method == "POST":
nexturl = request.POST.get("nexturl", "")
uname = request.POST.get("uname", "")
upwd = request.POST.get("upwd", "")
print(uname, upwd, nexturl, request.get_full_path)
print(request.POST.get("next"))
user = authenticate(request, username=uname, password=upwd)
if user is not None:
if user.is_active:
login(request, user)
if nexturl:
print(uname, upwd, nexturl, request.get_full_path(), nexturl)
return redirect(nexturl)
else:
return HttpResponse("success")
else:
return HttpResponse("Account does not exist")
def logoutl(request):
logout(request)
return HttpResponse("Logged out successfully")
@login_required(login_url="/loginv/")
def temp_views(request):
return HttpResponse("ok")
Login Template (login.html)
<form action="{% url 'login' %}" method="POST">
{% csrf_token %}
Name: <input type="text" name="uname">
<br>
Password: <input type="password" name="upwd">
<br>
<input type="hidden" name="nexturl" value="{{ nexturl }}">
<input type="submit" value="Submit">
</form>
How It Works
- When an unauthenticated user tries to access
/01-temp/, the@login_requireddecorator redirects them to/loginv/?next=/01-temp/. - The
loginlview receives the GET request, extracts thenextparameter, and passes it to the template asnexturl. - The login form includes a hidden input field with the value of
nexturl. - On form submission (POST), the view retrieves
nexturlfrom the POST data. - After successful authentication, the view redirects the user to the URL stored in
nexturl, which is the originally requested page.
Screenshots
(Screenshots from the original article have been omitted as they are not essential for understanding the core logic.)
Logout
Logging out is straightforward – it clears the session and redirects to a confirmation page.
Conclusion
By passing the next parameter through a hidden form field, we can ensure users return to their intended page after login, providing a seamless authentication experience.