【发布时间】:2021-12-18 23:01:27
【问题描述】:
我有以下装饰器,当应用于不同的视图时效果很好:@otp_required(login_url='login') 在我的网站上:
装饰器
from django.contrib.auth.decorators import user_passes_test
from django_otp import user_has_device
from django_otp.conf import settings
def otp_required(view=None, redirect_field_name='next', login_url=None, if_configured=False):
"""
Similar to :func:`~django.contrib.auth.decorators.login_required`, but
requires the user to be :term:`verified`. By default, this redirects users
to :setting:`OTP_LOGIN_URL`.
:param if_configured: If ``True``, an authenticated user with no confirmed
OTP devices will be allowed. Default is ``False``.
:type if_configured: bool
"""
if login_url is None:
login_url = settings.OTP_LOGIN_URL
def test(user):
return user.is_verified() or (if_configured and user.is_authenticated and not user_has_device(user))
decorator = user_passes_test(test, login_url=login_url, redirect_field_name=redirect_field_name)
return decorator if (view is None) else decorator(view)
但是,我想将其转换为中间件,因为我想避免将装饰器应用于我网站上的每个视图,但无法正常工作。 我尝试修改我目前拥有的以下中间件,这些中间件仅适用于授权用户并且一直在工作,但根据上述装饰器,我希望此中间件也扩展为也需要 OTP:
中间件
from django.utils.deprecation import MiddlewareMixin
from django.urls import resolve, reverse
from django.http import HttpResponseRedirect
from wfi_workflow import settings
from django_otp import user_has_device
from django_otp.decorators import otp_required
from django_otp.middleware import is_verified
class LoginRequiredMiddleware(MiddlewareMixin):
"""
Middleware that requires a user to be authenticated to view any page other
than LOGIN_URL. Exemptions to this requirement can optionally be specified
in settings by setting a tuple of routes to ignore
"""
#@otp_required(login_url='login')
def process_request(self, request):
assert hasattr(request, 'user'), """
The Login Required middleware needs to be after AuthenticationMiddleware.
Also make sure to include the template context_processor:
'django.contrib.account.context_processors.account'."""
if not request.user.is_verified() and not request.path.startswith('/admin/') and not request.path.startswith('/account/' ):
current_route_name = resolve(request.path_info).url_name
if not current_route_name in settings.AUTH_EXEMPT_ROUTES:
return HttpResponseRedirect(reverse(settings.LOGIN_URL))
非常感谢您的帮助。
【问题讨论】:
-
你能分享
MIDDLEWARE的设置吗?
标签: django decorator django-middleware