gpt4 book ai didi

python - 具有隐藏所有网站页面的登录名和密码的 Django 中间件

转载 作者:太空宇宙 更新时间:2023-11-03 12:03:18 24 4
gpt4 key购买 nike

我编写了以下中间件,它呈现表单并要求用户输入登录名和密码。中间件应该应用于整个网站:

class InviteLoginForWebsiteMiddleware(object):

def process_request(self, request):
if request.session.get('has_invite') == True:
return None

form = WebsiteLoginForm()
extra_context = dict()
extra_context['form'] = form
template_name = 'websiteLogin.html'

if request.method == "POST":
form = WebsiteLoginForm(request.POST)
if form.is_valid():
login = form.cleaned_data['login']
password = form.cleaned_data['password']

if login == "mylogin" and password == "mypassword":
request.session['has_inv'] = True
return None

return ExtraContextTemplateView.as_view(template_name=template_name, extra_context=extra_context)(request)

此解决方案的问题是,当我在 process_request 中创建表单时,呈现的页面上缺少 csrf token 。我一直在寻找答案,发现开发人员建议生成表单并在 process_view

中处理它

将所有代码移动到 process_view 后,如下所示:

def process_view(self, request, view_func, view_args, view_kwargs):
if request.session.get('has_inv') == True:
return None

form = WebsiteLoginForm()
extra_context = dict()
extra_context['form'] = form
template_name = 'websiteLogin.html'

if request.method == "POST":
form = WebsiteLoginForm(request.POST)
if form.is_valid():
login = form.cleaned_data['login']
password = form.cleaned_data['password']

if login == "mylogin" and password == "mypassword":
request.session['has_inv'] = True
return None

return ExtraContextTemplateView.as_view(template_name=template_name, extra_context=extra_context)(request)

代码开始运行,生成了 csrf token ,我可以提交带有登录名和密码的表单。

当用户输入诸如 www.mysite.com/notworkingurl/ 之类的无效页面时,就会出现问题。在这种情况下,process_view 不工作,引发 404 错误,用户被重定向到部分显示网络应用程序界面的页面。而且,当然,我希望中间件应该隐藏应用程序的所有页面。

再一次:

  1. 当我将代码放入 process_request 时,我可以接听任何电话到网站上的任何页面,但不呈现 csrf。结果,当用户提交表单时出现 csrf 错误。
  2. 当我放置 process_view 中的代码一切正常 它存在的情况。如果它不存在,则根据以下重定向用户 404 和其他异常网址。我不希望这种重定向发生。

有人可以建议解决这个问题的好方法吗?

解决方案:

感谢@knbk 的建议,一种可能的解决方案是使用 csrf_protect 装饰器。为了实现这个想法,我修改了我的 View 类,如下所示:

class ExtraContextTemplateViewCsrfProtect(TemplateView):
extra_context = None

@method_decorator(csrf_protect)
def dispatch(self, request, *args, **kwargs):
return super(ExtraContextTemplateViewCsrfProtect, self).dispatch(request, *args, **kwargs)

def get_context_data(self, *args, **kwargs):
context = super(ExtraContextTemplateViewCsrfProtect, self).get_context_data(*args, **kwargs)
if self.extra_context:
context.update(self.extra_context)
return context

post = TemplateView.get

最佳答案

您的中间件不仅缺少 csrf token ,它还容易受到 CSRF 攻击

如果你想使用这个模式,而不是重定向到一个单一的登录 View ,你应该将所有的表单逻辑移动到实际的 View 中。然后,您可以使用 csrf_protect 来保护 View 免受 CSRF 攻击,这也使您能够在模板中使用 token :

class InviteLoginForWebsiteMiddleware(object):

def process_request(self, request):
if request.session.get('has_invite') == True:
return None

return csrf_protect(CustomLoginView.as_view())(request)

不过,我会推荐matox建议的方法。

关于python - 具有隐藏所有网站页面的登录名和密码的 Django 中间件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40765550/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com