python – 具有登录名和密码的Django中间件,隐藏了所有网站页面
我写了下面的中间件,它们呈现表单并询问用户登录名和密码.中间件应该应用于整个网站:
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标记.我找到了答案,发现开发人员建议生成表单并在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令牌,我能够使用登录名和密码提交表单. 当用户输入非有效页面时会出现问题,例如www.mysite.com/notworkingurl/.在这种情况下,process_view不起作用,引发404错误,用户被重定向到页面,该页面部分显示了Web应用程序的界面.当然,我希望中间件应该隐藏应用程序的所有页面. 再来一次: >当我将代码放在process_request中时,我可以捕获任何调用 有人可以建议任何解决这个问题的好方法吗? 解: 感谢@knbk的建议,可能的解决方案之一是使用csrf_protect装饰器.为了使这个想法有效,我修改了我的视图类,如下所示: class ExtraContextTemplateViewCsrfProtect(TemplateView): extra_context = None @method_decorator(csrf_protect) def dispatch(self,*args,**kwargs): return super(ExtraContextTemplateViewCsrfProtect,self).dispatch(request,**kwargs) def get_context_data(self,**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令牌,而且容易受到CSRF攻击.
如果要使用此模式,而不是重定向到单个登录视图,则应将所有表单逻辑移动到实际视图中.然后,您可以使用csrf_protect保护视图免受CSRF攻击,这也使您可以在模板中使用令牌: 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建议的方法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |