简体   繁体   English

Django CSRF Cookie 未设置

[英]Django CSRF Cookie Not Set

I have some problem for a while now, I'm experiencing CSRF Cookie not set.我现在有一些问题,我遇到了 CSRF Cookie not set。 Please look at the codes below请看下面的代码

Python 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))

In the HTML here is the code在 HTML 这里是代码

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>

Im stuck, I already cleared the cookie, used other browser but still csrf cookie not set.我卡住了,我已经清除了 cookie,使用了其他浏览器但仍然没有设置 csrf cookie。

如果设置了CSRF_COOKIE_SECURE = True并且您以非安全方式访问站点,或者如果CSRF_COOKIE_HTTPONLY = True设置为此处此处所述,也会发生这种情况

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")

If you're using the HTML5 Fetch API to make POST requests as a logged in user and getting Forbidden (CSRF cookie not set.) , it could be because by default fetch does not include session cookies, resulting in Django thinking you're a different user than the one who loaded the page.如果您使用HTML5 Fetch API以登录用户身份发出 POST 请求并获取Forbidden (CSRF cookie not set.) ,这可能是因为默认情况下fetch不包括会话 cookie,导致 Django 认为您是与加载页面的用户不同。

You can include the session token by passing the option credentials: 'include' to fetch:您可以通过传递选项credentials: 'include'来包含会话令牌credentials: 'include'以获取:

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

From This You can solve it by adding the ensure_csrf_cookie decorator to your view这里您可以通过将ensure_csrf_cookie 装饰器添加到您的视图来解决它

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

if this method doesn't work.如果这个方法不起作用。 you will try to comment csrf in middleware.您将尝试在中间件中注释 csrf。 and test again.并再次测试。

If you're using DRF, check if your urlpatterns are correct, maybe you forgot .as_view() :如果您使用的是 DRF,请检查您的 urlpatterns 是否正确,也许您忘记了.as_view()

So that how mine code looked like:所以我的代码看起来像:

urlpatterns += path('resource', ResourceView) 

And that's how it should like:它应该是这样的:

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

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

try to check if your have installed in the settings.py尝试检查您是否已安装在 settings.py 中

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

In the template the data are formatted with the csrf_token:在模板中,数据使用 csrf_token 进行格式化:

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

This problem arose again recently due to a bug in Python itself.由于 Python 本身的错误,这个问题最近再次出现。

http://bugs.python.org/issue22931 http://bugs.python.org/issue22931

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

Among the versions affected were 2.7.8 and 2.7.9.受影响的版本包括 2.7.8 和 2.7.9。 The cookie was not read correctly if one of the values contained a [ character.如果其中一个值包含[字符,则无法正确读取 cookie。

Updating Python (2.7.10) fixes the problem.更新 Python (2.7.10) 解决了这个问题。

This also occurs when you don't set the form action.当您未设置表单操作时,也会发生这种情况。
For me, it was showing this error when the code was:对我来说,当代码为:

<form class="navbar-form form-inline my-2 my-lg-0" role="search" method="post">

When I corrected my code into this:当我更正我的代码时:

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

my error disappeared.我的错误消失了。

Problem seems that you are not handling GET requests appropriately or directly posting the data without first getting the form.问题似乎是您没有正确处理GET请求,或者没有先获取表单就直接发布数据。

When you first access the page, client will send GET request, in that case you should send html with appropriate form.当您第一次访问该页面时,客户端将发送GET请求,在这种情况下,您应该以适当的形式发送 html。

Later, user fills up the form and sends POST request with form data.稍后,用户填写表单并发送带有表单数据的POST请求。

Your view should be:你的观点应该是:

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))

Check that chrome's cookies are set with default option for websites.检查 chrome 的 cookie 是否设置为网站的默认选项。 Allow local data to be set (recommended).允许设置本地数据(推荐)。

Method 1:方法一:

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

Method 2 :方法二:

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

Because render_to_response method may case some problem of response cookies.因为 render_to_response 方法可能会导致响应 cookie 的一些问题。

I have just met once, the solution is to empty the cookies.刚遇到过一次,解决办法是清空cookies。 And may be changed while debugging SECRET_KEY related.并且在调试时可能会更改SECRET_KEY相关。

Clearing my browser's cache fixed this issue for me.清除浏览器的缓存为我解决了这个问题。 I had been switching between local development environments to do the django-blog-zinnia tutorial after working on another project when it happened.在完成另一个项目后,我一直在本地开发环境之间切换,以完成 django-blog-zinnia 教程。 At first, I thought changing the order of INSTALLED_APPS to match the tutorial had caused it, but I set these back and was unable to correct it until clearing the cache.起初,我认为更改 INSTALLED_APPS 的顺序以匹配教程导致了它,但是我将这些设置回原位并且在清除缓存之前无法更正它。

I was using Django 1.10 before.So I was facing this problem.我之前使用的是 Django 1.10。所以我遇到了这个问题。 Now I downgraded it to Django 1.9 and it is working fine.现在我将它降级到 Django 1.9,它运行良好。

Make sure your django session backend is configured properly in settings.py.确保在 settings.py 中正确配置了 django 会话后端。 Then try this,那就试试这个

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

Add this middleware in settings.py under MIDDLEWARE_CLASSES or MIDDLEWARE depending on the django version根据 django 版本在MIDDLEWARE_CLASSESMIDDLEWARE下的settings.py添加此中间件

get_token - Returns the CSRF token required for a POST form. get_token - 返回 POST 表单所需的 CSRF 令牌。 The token is an alphanumeric value.令牌是一个字母数字值。 A new token is created if one is not already set.如果尚未设置,则会创建一个新令牌。

I had the same error, in my case adding method_decorator helps:我有同样的错误,在我的情况下添加 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):
    ...

If you are not using {% csrf_token %} tag in the template you are rendering.如果您没有在正在渲染的模板中使用{% csrf_token %}标记。 Django won't set the csrftoken cookie. Django 不会设置csrftoken cookie。

To force django to set the csrftoken cookie, add ensure_csrf_cookie decorator in you view.要强制 django 设置 csrftoken cookie,在您的视图中添加ensure_csrf_cookie装饰器。

from django.views.decorators.csrf import ensure_csrf_cookie

@ensure_csrf_cookie
def myview(request):

In my particular case, the problem is that I was using the Django rest_framework and forgot to add the following decorators to my function:在我的特殊情况下,问题是我使用的是 Django rest_framework并忘记将以下装饰器添加到我的 function 中:

from rest_framework.decorators import api_view, renderer_classes

@api_view(('POST',))
@renderer_classes((JSONRenderer,))
def handle_web_request(request):
    ...

Just want to point out my case here as someone might cross the same fields.只是想在这里指出我的情况,因为有人可能会跨越相同的领域。

Forbidden (CSRF cookie not set.): /main/staff/products/validation/create
HTTP POST /main/staff/products/validation/create 403 [0.01, 127.0.0.1:55940]

This thing was driving me insane... So, by commenting CSRF middleware这件事让我发疯了......所以,通过评论 CSRF 中间件

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

it gave me它给了我

POST Method not allowed.

That was my hint, after all.毕竟这是我的暗示。 I was sure Post method was present.我确信 Post 方法存在。 Turns out my url_patterns was leading to another view by a regex bug.原来我的url_patterns导致了正则表达式错误的另一个视图。

So no matter what I was doing in my view, @csrf_exempt @ensure_crsf_cookie , looking for .as_view() ... I was looking at the wrong view.所以不管我在做什么, @csrf_exempt @ensure_crsf_cookie ,寻找.as_view() ...我看错了。

So, if nothing works, make sure your are actually being sent to the right view.因此,如果没有任何效果,请确保您实际上被发送到正确的视图。

You can get this error while deploing Django application with NO SSL.在部署没有 SSL 的 Django 应用程序时,您可能会遇到此错误。 If this is the case then putting an SSL reverse-proxy or SSL-configured Ingress in front of backend will solve the problem.如果是这种情况,那么在后端前面放置一个 SSL 反向代理或 SSL 配置的 Ingress 将解决问题。

I get this error and change this:我得到这个错误并改变它:

<form method="post">

to this:对此:

<form method="POST">

and it's solved.它解决了。 Just upper case post make the problem.只是大写的帖子会造成问题。 I doesn't have any issue with this on 127.0,0.1.我在 127.0,0.1 上对此没有任何问题。 but when i use 192.168.xx address this broke my forms.但是当我使用 192.168.xx 地址时,这打破了我的表格。

This is because Django by default includes a CSRF middleware called这是因为 Django 默认包含一个名为

django.middleware.csrf.CsrfViewMiddleware

During Development if you do not wish to utilise this feature just disable it from the middleware list.在开发过程中,如果您不想使用此功能,只需从中间件列表中禁用它即可。 Read more about it here .在此处阅读更多相关信息。 This is how you do it in the settings file.这就是您在设置文件中执行此操作的方式。

# Middleware framework
# https://docs.djangoproject.com/en/2.1/topics/http/middleware/
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

In my case, setting CSRF_COOKIE_SECURE to False wasn't enough but setting it to Null / not specifying the parameter worked.就我而言,将CSRF_COOKIE_SECURE设置为False还不够,但将其设置为Null / 未指定参数有效。

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

from django.views.decorators.csrf import csrf_protect

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM