Django CSRF Coo​​kie未设置

时间:2013-07-18 06:58:56

标签: python django

我现在有一些问题,我遇到CSRF Coo​​kie没有设置。请查看以下代码

的Python

def deposit(request,account_num):
if request.method == 'POST':
    account = get_object_or_404(account_info,acct_number=account_num)
    form_=AccountForm(request.POST or None, instance=account)
    form = BalanceForm(request.POST)
    info = str(account_info.objects.filter(acct_number=account_num))
    inf=info.split()
    if form.is_valid():
    #cd=form.cleaned_data
        now = datetime.datetime.now()
        cmodel = form.save()
        cmodel.acct_number=account_num
        #RepresentsInt(cmodel.acct_number)
        cmodel.bal_change="%0.2f" % float(cmodel.bal_change)
        cmodel.total_balance="%0.2f" %(float(inf[1]) + float(cmodel.bal_change))
        account.balance="%0.2f" % float(cmodel.total_balance)
        cmodel.total_balance="%0.2f" % float(cmodel.total_balance)
        #cmodel.bal_change=cmodel.bal_change
        cmodel.issued=now.strftime("%m/%d/%y %I:%M:%S %p")
        account.recent_change=cmodel.issued
        cmodel.save()
        account.save()
        return HttpResponseRedirect("/history/" + account_num + "/")
    else:
        return render_to_response('history.html',
                          {'account_form': form},
                          context_instance=RequestContext(request))

在HTML中这里是代码

HTML

<form action="/deposit/{{ account_num }}/" method="post">

<table>
<tr>
{{ account_form.bal_change }}
&nbsp;
<input type="submit" value="Deposit" />
</tr>
{% csrf_token %}
</table>
</form>

我卡住了,我已经清除了cookie,使用了其他浏览器,但仍未设置csrf cookie。

19 个答案:

答案 0 :(得分:100)

如果设置了CSRF_COOKIE_SECURE = True并且您正在非安全地访问该网站,也会发生这种情况。

答案 1 :(得分:43)

conditions

答案 2 :(得分:16)

如果您使用HTML5 Fetch API作为登录用户发送POST请求并获取Forbidden (CSRF cookie not set.),则可能是因为默认情况下fetch不包含会话Cookie,导致Django认为你的用户与加载页面的用户不同。

您可以通过将选项credentials: 'include'传递给fetch:

来包含会话令牌
var csrftoken = getCookie('csrftoken');
var headers = new Headers();
headers.append('X-CSRFToken', csrftoken);
fetch('/api/upload', {
    method: 'POST',
    body: payload,
    headers: headers,
    credentials: 'include'
})

答案 3 :(得分:7)

来自This 您可以通过在视图中添加ensure_csrf_cookie decorator来解决此问题

from django.views.decorators.csrf import ensure_csrf_cookie
@ensure_csrf_cookie
def yourView(request):
 #...

如果此方法不起作用。你会尝试在中间件中评论csrf。并再次测试。

答案 4 :(得分:4)

如果您使用的是DRF,请检查您的url模式是否正确,也许您忘记了.as_view()

这样,我的代码看起来像这样:

urlpatterns += path('resource', ResourceView) 

这就是应该的样子:

urlpatterns += path('resource', ResourceView.as_view())

答案 5 :(得分:2)

我在使用DRF时遇到了类似的情况,解决方案是将.as_view()方法附加到urls.py中的View

答案 6 :(得分:1)

当您未设置表单操作时也会发生这种情况。
对我来说,当代码为

时,它显示了此错误:
<form class="navbar-form form-inline my-2 my-lg-0" role="search" method="post">

当我将代码更正为此时:

<form class="navbar-form form-inline my-2 my-lg-0" action="{% url 'someurl' %}" role="search" method="post">

我的错误消失了。

答案 7 :(得分:1)

由于Python本身存在一个错误,最近又出现了这个问题。

http://bugs.python.org/issue22931

https://code.djangoproject.com/ticket/24280

受影响的版本包括2.7.8和2.7.9。 如果其中一个值包含[字符,则无法正确读取cookie。

更新Python(2.7.10)解决了这个问题。

答案 8 :(得分:1)

之前我正在使用Django 1.10。所以我遇到了这个问题。 现在我将它降级为Django 1.9,它运行正常。

答案 9 :(得分:0)

如果您在渲染的模板中没有使用 {% csrf_token %} 标记。 Django 不会设置 csrftoken cookie。

要强制 django 设置 csrftoken cookie,请在您的视图中添加 ensure_csrf_cookie 装饰器。

from django.views.decorators.csrf import ensure_csrf_cookie

@ensure_csrf_cookie
def myview(request):

答案 10 :(得分:0)

尝试检查您是否已安装在settings.py

 MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',)

在模板中,数据使用csrf_token格式化:

<form>{% csrf_token %}
</form>

答案 11 :(得分:0)

我遇到了同样的错误,以我为例,添加method_decorator会有所帮助:

from django.views.decorators.csrf import csrf_protect
from django.utils.decorators import method_decorator

method_decorator(csrf_protect)
def post(self, request):
    ...

答案 12 :(得分:0)

确保在settings.py中正确配置了django会话后端。然后试试这个,

class CustomMiddleware(object):
  def process_request(self,request:HttpRequest):
      get_token(request)

settings.pyMIDDLEWARE_CLASSESMIDDLEWARE下添加此中间件,具体取决于django版本

get_token - 返回POST表单所需的CSRF令牌。令牌是字母数字值。如果尚未设置新令牌,则会创建新令牌。

答案 13 :(得分:0)

方法1:

from django.shortcuts import render_to_response
return render_to_response(
    'history.html',
    RequestContext(request, {
        'account_form': form,
    })

方法2:

from django.shortcuts import render
return render(request, 'history.html', {
    'account_form': form,
})

因为render_to_response方法可能会出现响应cookie的某些问题。

答案 14 :(得分:0)

检查Chrome的Cookie是否设置为网站的默认选项。允许设置本地数据(推荐)。

答案 15 :(得分:0)

问题似乎是您未正确处理GET个请求或直接发布数据而未先获取表单。

当您第一次访问该页面时,客户端将发送GET请求,在这种情况下,您应该发送带有适当格式的HTML。

稍后,用户填写表单并向表单数据发送POST请求。

您的观点应该是:

def deposit(request,account_num):
   if request.method == 'POST':
      form_=AccountForm(request.POST or None, instance=account)
      if form.is_valid(): 
          #handle form data
          return HttpResponseRedirect("/history/" + account_num + "/")
      else:
         #handle when form not valid
    else:
       #handle when request is GET (or not POST)
       form_=AccountForm(instance=account)

    return render_to_response('history.html',
                          {'account_form': form},
                          context_instance=RequestContext(request))

答案 16 :(得分:-1)

清除浏览器的缓存为我解决了这个问题。我曾经在本地开发环境之间进行切换,以便在发生另一个项目后进行django-blog-zinnia教程。起初,我想改变INSTALLED_APPS的顺序以匹配教程导致它,但是我将它们设置回来并且在清除缓存之前无法纠正它。

答案 17 :(得分:-1)

我刚认识过一次,解决方法是清空cookie。 调试SECRET_KEY时可能会更改。

答案 18 :(得分:-3)

在你看来你使用的是csrf装饰器吗?

from django.views.decorators.csrf import csrf_protect

@csrf_protect def view(request, params): ....