diff --git a/note_kfet/middlewares.py b/note_kfet/middlewares.py
index 360132bf0c330abd608943499b607180093199b1..e2b8d7c693f15c481c6d9253e927146174d8161f 100644
--- a/note_kfet/middlewares.py
+++ b/note_kfet/middlewares.py
@@ -1,52 +1,64 @@
 # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
 # SPDX-License-Identifier: GPL-3.0-or-later
 
-from urllib3.packages.rfc3986 import urlparse
-
-try:
-    from django.utils.deprecation import MiddlewareMixin
-except ImportError:
-    MiddlewareMixin = object
-from django.http import HttpResponseForbidden
-
-
-def same_origin(current_uri, redirect_uri):
-    a = urlparse(current_uri)
-    if not a.scheme:
-        return True
-    b = urlparse(redirect_uri)
-    return (a.scheme, a.hostname, a.port) == (b.scheme, b.hostname, b.port)
-
-
-class TurbolinksMiddleware(MiddlewareMixin):
-
-    def process_request(self, request):
-        referrer = request.META.get('HTTP_X_XHR_REFERER')
-        if referrer:
-            # overwrite referrer
-            request.META['HTTP_REFERER'] = referrer
-        return
-
-    def process_response(self, request, response):
-        referrer = request.META.get('HTTP_X_XHR_REFERER')
-        if not referrer:
-            # turbolinks not enabled
-            return response
-
-        method = request.COOKIES.get('request_method')
-        if not method or method != request.method:
-            response.set_cookie('request_method', request.method)
-
-        if response.has_header('Location'):
-            # this is a redirect response
-            loc = response['Location']
-            request.session['_turbolinks_redirect_to'] = loc
-
-            # cross domain blocker
-            if referrer and not same_origin(loc, referrer):
-                return HttpResponseForbidden()
-        else:
-            if request.session.get('_turbolinks_redirect_to'):
-                loc = request.session.pop('_turbolinks_redirect_to')
-                response['X-XHR-Redirected-To'] = loc
+from django.http import HttpResponseRedirect
+
+from urllib.parse import urlencode, parse_qs, urlsplit, urlunsplit
+
+
+class SmoothNavigationMiddleware(object):
+    """Keep `?back=` queryset parameter on POST requests."""
+    def __init__(self, get_response):
+        self.get_response = get_response
+
+    def __call__(self, request):  # noqa D102
+        response = self.get_response(request)
+
+        if isinstance(response, HttpResponseRedirect):
+            back = request.GET.get('back')
+            if back:
+                _, _, back_path, _, _ = urlsplit(back)
+                scheme, netloc, path, query_string, fragment = urlsplit(response['location'])
+                query_params = parse_qs(query_string)
+
+                if path == back_path:
+                    query_params.pop('back', None)
+                elif 'back' not in query_params:
+                    query_params['back'] = [back]
+
+                new_query_string = urlencode(query_params, doseq=True)
+                response['location'] = urlunsplit((scheme, netloc, path, new_query_string, fragment))
+
         return response
+
+
+class TurbolinksMiddleware(object):
+    """
+    Send the `Turbolinks-Location` header in response to a visit that was redirected,
+    and Turbolinks will replace the browser's topmost history entry.
+    """
+
+    def __init__(self, get_response):
+        self.get_response = get_response
+
+    def __call__(self, request):
+        response = self.get_response(request)
+
+        is_turbolinks = request.META.get('HTTP_TURBOLINKS_REFERRER')
+        is_response_redirect = response.has_header('Location')
+
+        if is_turbolinks:
+            if is_response_redirect:
+                location = response['Location']
+                prev_location = request.session.pop('_turbolinks_redirect_to', None)
+                if prev_location is not None:
+                    # relative subsequent redirect
+                    if location.startswith('.'):
+                        location = prev_location.split('?')[0] + location
+                request.session['_turbolinks_redirect_to'] = location
+            else:
+                if request.session.get('_turbolinks_redirect_to'):
+                    location = request.session.pop('_turbolinks_redirect_to')
+                    response['Turbolinks-Location'] = location
+        return response
+
diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py
index 9019b4e07c39a3a0588e91bec7c7b580a4d2d4ba..b45dc55cb694c206f38e123b4c094fd3485fc2fc 100644
--- a/note_kfet/settings/base.py
+++ b/note_kfet/settings/base.py
@@ -75,6 +75,7 @@ MIDDLEWARE = [
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'django.middleware.locale.LocaleMiddleware',
     'django.contrib.sites.middleware.CurrentSiteMiddleware',
+    'note_kfet.middlewares.SmoothNavigationMiddleware',
     'note_kfet.middlewares.TurbolinksMiddleware',
 ]