Django:CSRF 令牌丢失或不正确

发布于 2024-12-18 14:29:27 字数 1693 浏览 0 评论 0原文

错误位于位置 http://127.0.0.1:8000/fileupload/form.py

我有 django 1.3 版本。我尝试按照其他人的问题中所述指定 localhost:8000 但这对我不起作用。我正在尝试创建文件上传表单,但收到错误消息,指出 form.py 没有 CSRF 令牌。

form.py:views.py:upload.html

class UploadFileForm(forms.Form):

    title = forms.CharField(max_length=50)
    file  = forms.FileField()

def upload_file(request):

    c = {}
    c.update(csrf(request))

    if (not request.user.is_authenticated()) or (request.user == None):
      return HttpResponseRedirect("/?error=11")


    if request.method == 'POST':
      form = c['UploadFileForm'] = UploadFileForm(request.POST, request.FILES,  c, context_instance=RequestContext(request))

      if c['UploadFileForm'].is_valid():
        handle_uploaded_file(request.FILES['file'])
        return HttpResponseRedirect('/success/url/')

    else:
        form = c['UploadFileForm'] = UploadFileForm()
    return render_to_response('fileupload/upload.html', {'form': c['UploadFileForm']})

{% block main_content %}


  <form action="fileupload/form.py" enctype="multipart/form-data" method="POST">
    {% csrf_token %}
    <table>

      <tr><td>Title:</td><td><input type="text" name="title" /></td></tr>
      <tr><td>File:</td><td><input type="file" name="file" /></td></tr>
    </table>
      <input type="submit" value="Submit" class = "float_right button_input" />

  </form> 

{% endblock main_content %}

我很困惑,请告诉我一些要尝试的事情 谢谢

The error is at location http://127.0.0.1:8000/fileupload/form.py

I have version 1.3 of django. I have tried specifying localhost:8000 as stated in someone else's question but this did not work for me. I am trying to have a file upload form but I am receiving an error that form.py does not have the CSRF token.

form.py:

class UploadFileForm(forms.Form):

    title = forms.CharField(max_length=50)
    file  = forms.FileField()

views.py:

def upload_file(request):

    c = {}
    c.update(csrf(request))

    if (not request.user.is_authenticated()) or (request.user == None):
      return HttpResponseRedirect("/?error=11")


    if request.method == 'POST':
      form = c['UploadFileForm'] = UploadFileForm(request.POST, request.FILES,  c, context_instance=RequestContext(request))

      if c['UploadFileForm'].is_valid():
        handle_uploaded_file(request.FILES['file'])
        return HttpResponseRedirect('/success/url/')

    else:
        form = c['UploadFileForm'] = UploadFileForm()
    return render_to_response('fileupload/upload.html', {'form': c['UploadFileForm']})

upload.html:

{% block main_content %}


  <form action="fileupload/form.py" enctype="multipart/form-data" method="POST">
    {% csrf_token %}
    <table>

      <tr><td>Title:</td><td><input type="text" name="title" /></td></tr>
      <tr><td>File:</td><td><input type="file" name="file" /></td></tr>
    </table>
      <input type="submit" value="Submit" class = "float_right button_input" />

  </form> 

{% endblock main_content %}

I am very stumped please tell me some things to try. Thank You

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

绻影浮沉 2024-12-25 14:29:27

您需要在 render_to_response 中为 csrf_token 传递 RequestContext

为此:(views.py)

from django.template import RequestContext

...

return render_to_response('fileupload/upload.html', {'form': c['UploadFileForm']},  RequestContext(request))
# Added RequestContext

这会将 csrf 的令牌传递给模板。

You need to pass RequestContext in render_to_response for csrf_token

For this : (views.py)

from django.template import RequestContext

...

return render_to_response('fileupload/upload.html', {'form': c['UploadFileForm']},  RequestContext(request))
# Added RequestContext

This passes the token for csrf to the template.

萌面超妹 2024-12-25 14:29:27

如果您使用 @cache_page(60 * 15) 装饰器,也可能会发生这种情况。如果您缓存包含 CSRF 令牌的表单的页面,则将仅缓存第一个用户的 CSRF 令牌。所以有时候调试起来有点困难。

更多信息来自 Django 文档

如果模板使用了csrf_token模板标签(或者get_token
函数以其他方式调用),CsrfViewMiddleware 将添加一个
cookie 和响应的 Vary: Cookie 标头。这意味着
如果用作缓存中间件,中间件将与缓存中间件配合良好
指示(UpdateCacheMiddleware 优先于所有其他中间件)。

但是,如果您在各个视图上使用缓存装饰器,CSRF
中间件还无法设置 Vary 标头或
CSRF cookie,并且响应将在没有任何一个的情况下被缓存。在
在这种情况下,在任何需要插入 CSRF 令牌的视图上
你应该使用django.views.decorators.csrf.csrf_protect()
首先是装饰器:

从 django.views.decorators.cache 导入cache_page
从 django.views.decorators.csrf 导入 csrf_protect

@cache_page(60 * 15)
@csrf_protect
def my_view(请求):
    ...

It can also happen if you use @cache_page(60 * 15) decorators. If you cache a page with a form containing a CSRF token, you'll cache the CSRF token of the first user only. So it's kinda hard to debug sometimes.

More info from Django documentation

If the csrf_token template tag is used by a template (or the get_token
function is called some other way), CsrfViewMiddleware will add a
cookie and a Vary: Cookie header to the response. This means that the
middleware will play well with the cache middleware if it is used as
instructed (UpdateCacheMiddleware goes before all other middleware).

However, if you use cache decorators on individual views, the CSRF
middleware will not yet have been able to set the Vary header or the
CSRF cookie, and the response will be cached without either one. In
this case, on any views that will require a CSRF token to be inserted
you should use the django.views.decorators.csrf.csrf_protect()
decorator first:

from django.views.decorators.cache import cache_page
from django.views.decorators.csrf import csrf_protect

@cache_page(60 * 15)
@csrf_protect
def my_view(request):
    ...
旧时光的容颜 2024-12-25 14:29:27

我的答案与上面 @Yugal Jindle 的答案类似。

我正在使用 Django 1.10,我遇到了类似的问题,在编辑 P.S. 后它对我

return render_to_response(param1, param2)

有用

return render(request, param1, param2)

。确保 settings.py 中的 MIDDLEWARE 变量中有以下行

'django.middleware.csrf.CsrfViewMiddleware'

My answer is similar to the @Yugal Jindle's answer above.

I am using Django 1.10 and I had a similar issue, it worked for me after editing

return render_to_response(param1, param2)

to

return render(request, param1, param2)

P.S. Make sure you have the below line in your MIDDLEWARE variable in the settings.py

'django.middleware.csrf.CsrfViewMiddleware'
没企图 2024-12-25 14:29:27

对于我的情况,我使用 AJAX 将数据发布到我的视图函数,然后发生相同的错误,因此解决它的简单方法是将数据从

data:{ 'k':'v' }

To

data:{ 'k':'v' ,addcsrfmiddlewaretoken:'{{ csrf_token }}',}

更改为因为我们手动添加 csrf-token,所以它不会丢失或不正确。

For my case, I use AJAX to post data to my views function, then the same error happens, so the easy method to solve it is to change the data from

data:{ 'k':'v' }

To

data:{ 'k':'v' ,addcsrfmiddlewaretoken:'{{ csrf_token }}',}

because we manually add a csrf-token, so it is not missing or incorrect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文