加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

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

发布时间:2020-12-20 13:15:14 所属栏目:Python 来源: class InviteLoginForWebsiteMi
导读:我写了下面的中间件,它们呈现表单并询问用户登录名和密码.中间件应该应用于整个网站: class InviteLoginForWebsiteMiddleware(object): def process_request(self,request): if request.session.get('has_invite') == True: return None form = WebsiteLogi
我写了下面的中间件,它们呈现表单并询问用户登录名和密码.中间件应该应用于整个网站:

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中时,我可以捕获任何调用
到网站上的任何页面,但不呈现csrf.结果当用户提交表单时引发了csrf错误.
>当我放置
????process_view中的代码一切都在为页面工作
????它存在的情况.如果不存在则根据用户重定向
????404和其他例外网址.而且我不希望这种重定向发生.

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

解:

感谢@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建议的方法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读