在Django项目中使用中间件class进行用户认证
Using middleware class for user authentication in Django project
我公司的一个项目是在Django中,我被分配了一个任务给'add authentication to the top-level router'所以我们不要忘记为每个视图添加一个验证码,例如:
if not request.user.is_authenticated:
return HttpResponseRedirect('/admin/login/?next=/admin/some-page/')
经过一番研究后,我发现这可以通过编写自己的中间件来实现。在做作业之前,我根本不熟悉这个概念。所以现在我正在尝试编写一个 LoginRequiredMiddleware
class 来拦截每个请求,如果未通过身份验证,则将用户发送到登录页面,并在身份验证后发送到用户尝试访问的原始页面。
这是我目前的代码。
middleware.py
from django.conf import settings
from django.http import HttpResponseRedirect
from django.utils.deprecation import MiddlewareMixin
from django.utils.http import is_safe_url
import re
EXEMPT_URLS = [re.compile(settings.LOGIN_REDIRECT_URL.lstrip('/'))] # '/admin'
class LoginRequiredMiddleware(MiddlewareMixin):
def process_request(self, request):
assert hasattr(request, 'user'), "The Login Required Middleware"
if not request.user.is_authenticated:
path = request.path_info.lstrip('/')
if not any(m.match(path) for m in EXEMPT_URLS):
redirect_to = settings.LOGIN_REDIRECT_URL
if len(path) > 0 and is_safe_url(
url=request.path_info, allowed_hosts=request.get_host()):
redirect_to = f"{settings.LOGIN_REDIRECT_URL}/login?next={request.path_info}"
return HttpResponseRedirect(redirect_to)
我已经在 settings.py
的 MIDDLEWARE
列表中注册了中间件,并且包括了 SessionMiddleware
和 AuthenticationMiddleware
,但我还没有设法让它工作。我可以在隐身模式下访问需要身份验证的页面,例如,无需登录。
我想要一些关于我做错了什么或我应该遵循哪条更好的道路的提示。
import re
from django.conf import settings
from django.shortcuts import redirect
from django.contrib.auth import logout
from django.utils.deprecation import MiddlewareMixin
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]
# Other login exempt urls can be added in settings with 'LOGIN_EXEMPT_URLS'
class LoginRequiredMiddleware(MiddlewareMixin):
def __init__(self, get_response):
self.get_response = get_response
def process_request(self, request):
assert hasattr(request, 'user')
path = request.path_info.lstrip('/')
for endpoint in ["api/", "settings", "mfa", "reset"]:
if path.startswith(endpoint):
return self.get_response(request)
url_is_exempt = any(url.match(path) for url in EXEMPT_URLS)
if path == settings.LOGOUT_URL.lstrip('/'):
logout(request)
if request.user.is_authenticated and url_is_exempt:
# If the user is authenticated and the URL is in the exempt list
# redirect to the login page
return redirect(settings.LOGIN_REDIRECT_URL)
elif request.user.is_authenticated or url_is_exempt:
# Do nothing if the user is authenticated and the URL is not in the
# exempt list
return None
else:
# Trying to access any page as a non authenticated user
return redirect(f"{settings.LOGIN_URL}?next=/{path}")
我公司的一个项目是在Django中,我被分配了一个任务给'add authentication to the top-level router'所以我们不要忘记为每个视图添加一个验证码,例如:
if not request.user.is_authenticated:
return HttpResponseRedirect('/admin/login/?next=/admin/some-page/')
经过一番研究后,我发现这可以通过编写自己的中间件来实现。在做作业之前,我根本不熟悉这个概念。所以现在我正在尝试编写一个 LoginRequiredMiddleware
class 来拦截每个请求,如果未通过身份验证,则将用户发送到登录页面,并在身份验证后发送到用户尝试访问的原始页面。
这是我目前的代码。
middleware.py
from django.conf import settings
from django.http import HttpResponseRedirect
from django.utils.deprecation import MiddlewareMixin
from django.utils.http import is_safe_url
import re
EXEMPT_URLS = [re.compile(settings.LOGIN_REDIRECT_URL.lstrip('/'))] # '/admin'
class LoginRequiredMiddleware(MiddlewareMixin):
def process_request(self, request):
assert hasattr(request, 'user'), "The Login Required Middleware"
if not request.user.is_authenticated:
path = request.path_info.lstrip('/')
if not any(m.match(path) for m in EXEMPT_URLS):
redirect_to = settings.LOGIN_REDIRECT_URL
if len(path) > 0 and is_safe_url(
url=request.path_info, allowed_hosts=request.get_host()):
redirect_to = f"{settings.LOGIN_REDIRECT_URL}/login?next={request.path_info}"
return HttpResponseRedirect(redirect_to)
我已经在 settings.py
的 MIDDLEWARE
列表中注册了中间件,并且包括了 SessionMiddleware
和 AuthenticationMiddleware
,但我还没有设法让它工作。我可以在隐身模式下访问需要身份验证的页面,例如,无需登录。
我想要一些关于我做错了什么或我应该遵循哪条更好的道路的提示。
import re
from django.conf import settings
from django.shortcuts import redirect
from django.contrib.auth import logout
from django.utils.deprecation import MiddlewareMixin
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]
# Other login exempt urls can be added in settings with 'LOGIN_EXEMPT_URLS'
class LoginRequiredMiddleware(MiddlewareMixin):
def __init__(self, get_response):
self.get_response = get_response
def process_request(self, request):
assert hasattr(request, 'user')
path = request.path_info.lstrip('/')
for endpoint in ["api/", "settings", "mfa", "reset"]:
if path.startswith(endpoint):
return self.get_response(request)
url_is_exempt = any(url.match(path) for url in EXEMPT_URLS)
if path == settings.LOGOUT_URL.lstrip('/'):
logout(request)
if request.user.is_authenticated and url_is_exempt:
# If the user is authenticated and the URL is in the exempt list
# redirect to the login page
return redirect(settings.LOGIN_REDIRECT_URL)
elif request.user.is_authenticated or url_is_exempt:
# Do nothing if the user is authenticated and the URL is not in the
# exempt list
return None
else:
# Trying to access any page as a non authenticated user
return redirect(f"{settings.LOGIN_URL}?next=/{path}")