zoukankan      html  css  js  c++  java
  • django种表单post出现CSRF verification failed( CSRF验证失败 ) 的两种解决方式

    现象

    表单界面例如以下:


    在点击提交之后,出现例如以下错误页面:



    HTML的代码例如以下:

    contact_form.html

    <!DOCTYPE HTML PUBLIC >
    
    <html>
    <head>
        <title>Contact us</title>
    </head>
    
    <body>
        <h1>Contact us</h1>
        {% if errors %}
           <ul>
              {% for error in errors %}
               <li>{{ error }}</li>
               {% endfor %}
           </ul>
        {% endif %}
        <form action="/contact/" method="post">
            <p>Subject: <input type="text" name="subject" value="{{ subject }}"></p>
            <p>Your e-mail (optional): <input type="text" name="email" value="{{ email }}"></p>
            <p>Message: <textarea name="message" rows="10" cols="50">{{ message }}</textarea></p>
            <input type="submit" value="Submit">
        </form>
    </body>
    </html>

    view代码例如以下:

    view.py

    # -*- coding: utf-8 -*-
    
    from django.core.mail import send_mail
    from django.http import HttpResponseRedirect
    from django.shortcuts import render_to_response
    
    def contact(request):
        errors = []
        if request.method == 'POST':
            if not request.POST.get('subject', ''):
                errors.append('Enter a subject.')
            if not request.POST.get('message', ''):
                errors.append('Enter a message.')
            if request.POST.get('email') and '@' not in request.POST['email']:
                errors.append('Enter a valid e‐mail address.')
            if not errors:
                send_mail(
                          request.POST['subject'],
                          request.POST['message'],
                          request.POST.get('email', 'noreply@example.com'),
                          ['siteowner@example.com'],
                          )
                return HttpResponseRedirect('/contact/thanks/')
        return render_to_response('contact_form.html', {
                                                        'errors': errors,
                                                        'subject': request.POST.get('subject', ''),
                                                        'message': request.POST.get('message', ''),
                                                        'email': request.POST.get('email', ''),
                                                        })

    一般浏览器都是开启了cookies的,所以在上面图中的错误信息中。我们主要关注后三点,依据提示进行更改:

    解决方式一:CSRF验证设置

    1. 在 view.py 中的 render_to_response 中,使用 RequestContext 来取代默认的 Context 。

    view.py

    # -*- coding: utf-8 -*-
    
    from django.core.mail import send_mail
    from django.http import HttpResponseRedirect
    from django.shortcuts import render_to_response
    from django.template import RequestContext
    
    def contact(request):
        errors = []
        if request.method == 'POST':
            if not request.POST.get('subject', ''):
                errors.append('Enter a subject.')
            if not request.POST.get('message', ''):
                errors.append('Enter a message.')
            if request.POST.get('email') and '@' not in request.POST['email']:
                errors.append('Enter a valid e‐mail address.')
            if not errors:
                send_mail(
                          request.POST['subject'],
                          request.POST['message'],
                          request.POST.get('email', 'noreply@example.com'),
                          ['siteowner@example.com'],
                          )
                return HttpResponseRedirect('/contact/thanks/')
        return render_to_response('contact_form.html', {
                                                        'errors': errors,
                                                        'subject': request.POST.get('subject', ''),
                                                        'message': request.POST.get('message', ''),
                                                        'email': request.POST.get('email', ''),
                                                        },context_instance=RequestContext(request))

    2. 在模板文件里的 form 表单内加入 {% csrf_token %} 。

    contact_form.html

    <!DOCTYPE HTML PUBLIC >
    
    <html>
    <head>
        <title>Contact us</title>
    </head>
    
    <body>
        <h1>Contact us</h1>
        {% if errors %}
           <ul>
              {% for error in errors %}
               <li>{{ error }}</li>
               {% endfor %}
           </ul>
        {% endif %}
        <form action="/contact/" method="post">
            <br />{% csrf_token %}<br />
            <p>Subject: <input type="text" name="subject" value="{{ subject }}"></p>
            <p>Your e-mail (optional): <input type="text" name="email" value="{{ email }}"></p>
            <p>Message: <textarea name="message" rows="10" cols="50">{{ message }}</textarea></p>
            <input type="submit" value="Submit">
        </form>
    </body>
    </html>

    測试执行,成功!

    PS:上文中图片中的错误信息第四条,在建立djangoproject的时候 setting.py 已经自己主动加入了 'django.middleware.csrf.CsrfViewMiddleware',

    MIDDLEWARE_CLASSES = (
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'django.middleware.security.SecurityMiddleware',
        'django.middleware.locale.LocaleMiddleware',
    )



    解决方式二:不使用 CSRF 验证

    1. 在 setting.py 文件里删除  'django.middleware.csrf.CsrfViewMiddleware', ,例如以下所看到的

    MIDDLEWARE_CLASSES = (
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        #'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'django.middleware.security.SecurityMiddleware',
        'django.middleware.locale.LocaleMiddleware',
    )
    

    2. 移除 form 表单中的  {% csrf_token %} 标记。例如以下所看到的:

    contact_form.html

    <!DOCTYPE HTML PUBLIC >
    
    <html>
    <head>
        <title>Contact us</title>
    </head>
    
    <body>
        <h1>Contact us</h1>
        {% if errors %}
           <ul>
              {% for error in errors %}
               <li>{{ error }}</li>
               {% endfor %}
           </ul>
        {% endif %}
        <form action="/contact/" method="post">
            <p>Subject: <input type="text" name="subject" value="{{ subject }}"></p>
            <p>Your e-mail (optional): <input type="text" name="email" value="{{ email }}"></p>
            <p>Message: <textarea name="message" rows="10" cols="50">{{ message }}</textarea></p>
            <input type="submit" value="Submit">
        </form>
    </body>
    </html>

    3. 在 view.py 中的 render_to_response 中,不使用 RequestContext 。例如以下所看到的:

    view.py

    # -*- coding: utf-8 -*-
    
    from django.core.mail import send_mail
    from django.http import HttpResponseRedirect
    from django.shortcuts import render_to_response
    from django.template import RequestContext
    
    def contact(request):
        errors = []
        if request.method == 'POST':
            if not request.POST.get('subject', ''):
                errors.append('Enter a subject.')
            if not request.POST.get('message', ''):
                errors.append('Enter a message.')
            if request.POST.get('email') and '@' not in request.POST['email']:
                errors.append('Enter a valid e‐mail address.')
            if not errors:
                send_mail(
                          request.POST['subject'],
                          request.POST['message'],
                          request.POST.get('email', 'noreply@example.com'),
                          ['siteowner@example.com'],
                          )
                return HttpResponseRedirect('/contact/thanks/')
        return render_to_response('contact_form.html', {
                                                        'errors': errors,
                                                        'subject': request.POST.get('subject', ''),
                                                        'message': request.POST.get('message', ''),
                                                        'email': request.POST.get('email', ''),
                                                        })

    又一次执行,測试成功!




  • 相关阅读:
    页面调用百度地图但是使用了https证书之后不显示
    JAVA查询类别(菜单)下的所有子类别(递归)
    summernote富文本的简单使用
    thymeleaf标签在js中调用转义变量与不转义变量写法
    SpringBoot使用@Async实现异步调用
    JAVA使用多线程进行数据处理
    MapReduce-TextInputFormat 切片机制
    BootstrapTable 导出数据
    BootstrapTable 加载数据
    CDN 常用静态资源公共库
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5331633.html
Copyright © 2011-2022 走看看