django post出现403的解决办法

据说,从django1.x开始,加入了CSRF保护。
CSRF(Cross-site request forgery跨站请求伪造,也被称成为“one click attack”或者session riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
——-来自百度百科
报错:

Forbidden (403)

CSRF verification failed. Request aborted.

Help

Reason given for failure:
CSRF token missing or incorrect.
In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django’s CSRF mechanism has not been used correctly. For POST forms, you need to ensure:
  • Your browser is accepting cookies.
  • The view function uses RequestContext for the template, instead of Context.
  • In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
  • If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
You’re seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.
You can customize this page using the CSRF_FAILURE_VIEW setting.
在网上找解决办法,说是提交参数中要有csrf_token,才能成功。但网上都是1.3或者1.4版本的解决办法,在1.5版本中测试已经不能用了。
在1.5.1版本,我测试可行的解决办法有三种:

一:

关闭csrf保护功能。为视图函数添加@csrf_exempt修饰符。

from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def view(request):
    #your code.....

当然这样不安全。

二:

       在模版文件中,每个form提交域中都加上{% csrf_token %}标签,并使用render函数返回视图,或者强行使用RequestContext 代替Context。
例:
from django.shortcuts import render
def contact(request):
    form = ContactForm()#这里我使用了一个django的表格
    return render(request,'contact.html', {'form': form})

或者:

from django.shortcuts import render_to_response
def contact(request):
    form = ContactForm()#这里我使用了一个django的表格
    return render_to_response('contact.html',
            {'form': form},
            context_instance=RequestContext(request)
        )
contact.html的内容:
<html>
<head>
<style type="text/css">
    ul.errorlist {
        margin: 0;
        padding: 0;
    }
    .errorlist li {
        background-color: red;
        color: white;
        display: block;
        font-size: 10px;
        margin: 0 0 3px;
        padding: 4px 5px;
    }
</style>
    <title>send</title>
</head>
<body>
    <h1>Contact us</h1>
    <form action="" method="post">
        {% csrf_token %}
        <div class="field">
            {{ form.subject.errors }}
            <label for="id_subject">工作:</label>
            {{ form.subject }}
        </div>
        <div class="field">
            {{ form.email.errors }}
            <label for="id_email">你的邮箱地址:</label>
            {{ form.email }}
        </div>
        <div class="field">
            {{ form.message.errors }}
            <label for="id_message">消息:</label>
            {{ form.message }}
        </div>
        <input type="submit" value="Submit">
    </form>
</body>
</html>

 

三:

方法二显然只能限制在django模版中使用,那如果我们使用javascript或者AJAX的时候呢?怎么添加csrf_token呢?

我们可以使用javascript来提取cookies中的csrf_token。

function getCookie(name) {  
        var cookieValue = null;  
        if (document.cookie && document.cookie != '') {  
            var cookies = document.cookie.split(';');  
            for (var i = 0; i < cookies.length; i++) {  
                var cookie = jQuery.trim(cookies[i]); 
                if (cookie.substring(0, name.length + 1) == (name + '=')) {  
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));  
                    break;  
                }  
            }  
        }  
        return cookieValue;  
    }

或者这个好理解的:

function getCookie(sName){
    var aCookie=document.cookie.split("; ");
    for(var i=0;i<aCookie.length;i++){
        var aCrumb=aCookie[i].split("=");
        if(sName==aCrumb[0])return (aCrumb[1]);
    }
    return null;
}

AJAX中这样用:

$.post(url,
    {"csrfmiddlewaretoken":getCookie('csrftoken')}, 
    function (data) {alert(data);});

 

但是有一个问题,当有一个新用户访问这个页面的时候,cookie里并没有csrftoken这个值。只有进行第二种方法,才能在cookie里生成csrftoken值。解决此问题的方法随后更新。

完全可以满足简单的建站需要。


搬瓦工优质海外服务器购买链接:http://t.cn/Rdru0Ah

使用优惠码 BWH26FXH3HIQ  最高减6%