103

我现在有一些问题,我遇到了 CSRF Coo​​kie not set。请看下面的代码

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。

4

20 回答 20

145

CSRF_COOKIE_SECURE = True如果已设置并且您正在不安全地访问该站点,或者如果按照此处此处CSRF_COOKIE_HTTPONLY = True的说明进行设置,也会发生这种情况

于 2013-09-25T15:04:56.117 回答
82
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt 
def your_view(request):
    if request.method == "POST":
        # do something
    return HttpResponse("Your response")
于 2016-07-29T16:17:19.983 回答
26

如果您使用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'
})
于 2017-04-15T00:21:45.953 回答
20

这里 您可以通过将ensure_csrf_cookie 装饰器添加到您的视图来解决它

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

如果这个方法不起作用。您将尝试在中间件中评论 csrf。并再次测试。

于 2016-06-27T10:40:40.637 回答
8

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

所以我的代码看起来像:

urlpatterns += path('resource', ResourceView) 

这就是它应该的样子:

urlpatterns += path('resource', ResourceView.as_view())
于 2020-02-20T14:41:17.150 回答
5

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

于 2018-03-20T12:21:26.163 回答
1

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

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

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

<form>{% csrf_token %}
</form>
于 2013-07-18T07:14:43.693 回答
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">

我的错误消失了。

于 2018-12-08T20:09:34.050 回答
1

由于 Python 本身的一个错误,这个问题最近再次出现。

http://bugs.python.org/issue22931

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

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

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

于 2015-10-08T10:12:12.897 回答
0

Check that chrome's cookies are set with default option for websites. Allow local data to be set (recommended).

于 2014-08-17T04:18:06.100 回答
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))
于 2013-07-18T08:19:09.810 回答
0

方法一:

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

方法二:

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

因为 render_to_response 方法可能会导致一些响应 cookie 的问题。

于 2015-06-16T13:33:53.690 回答
0

我刚遇到一次,解决办法是清空cookies。并且在调试SECRET_KEY相关的时候可能会改变。

于 2016-02-21T03:21:48.620 回答
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):
    ...
于 2018-07-18T09:15:50.590 回答
0

确保您的 django 会话后端在 settings.py 中正确配置。那就试试这个

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

settings.py在 django 版本下MIDDLEWARE_CLASSESMIDDLEWARE根据 django 版本添加此中间件

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

于 2017-02-15T17:40:17.023 回答
0

我之前使用的是 Django 1.10。所以我遇到了这个问题。现在我将它降级到 Django 1.9,它工作正常。

于 2016-08-09T09:45:26.977 回答
0

清除浏览器的缓存为我解决了这个问题。在另一个项目发生后,我一直在本地开发环境之间切换以完成 django-blog-zinnia 教程。起初,我认为更改 INSTALLED_APPS 的顺序以匹配教程导致它,但我将这些设置回来并且无法更正它,直到清除缓存。

于 2016-05-26T09:41:55.377 回答
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):
于 2021-07-05T16:17:45.133 回答
0

在我的特殊情况下,问题是我正在使用 Djangorest_framework并忘记将以下装饰器添加到我的函数中:

from rest_framework.decorators import api_view, renderer_classes

@api_view(('POST',))
@renderer_classes((JSONRenderer,))
def handle_web_request(request):
    ...
于 2022-02-28T14:17:44.633 回答
-4

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

from django.views.decorators.csrf import csrf_protect

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

于 2013-07-18T07:20:04.433 回答