Django CSRF Cookie未设置
我现在有一些问题,我没有设置CSRF Cookie。 请看下面的代码
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 }} <input type="submit" value="Deposit" /> </tr> {% csrf_token %} </table> </form>
我坚持,我已经清除cookie,使用其他浏览器,但仍没有设置csrf cookie。
如果设置了CSRF_COOKIE_SECURE = True
并且您CSRF_COOKIE_SECURE = 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")
你可以通过在你的视图中添加ensure_csrf_cookie装饰器来解决这个问题
from django.views.decorators.csrf import ensure_csrf_cookie @ensure_csrf_cookie def yourView(request): #...
如果这种方法不起作用。 你会尝试在中间件中评论csrf。 并再次testing。
如果您使用HTML5 Fetch API以POST请求作为login用户并获取Forbidden (CSRF cookie not set.)
,则可能是因为默认情况下, fetch
不包含会话cookie,导致Django认为您是与加载页面的用户不同。
您可以通过传递选项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' })
由于Python本身的错误,最近又出现了这个问题。
http://bugs.python.org/issue22931
https://code.djangoproject.com/ticket/24280
受影响的版本有2.7.8和2.7.9。 如果其中一个值包含[
字符,则Cookie未被正确读取。
更新Python(2.7.10)解决了这个问题。
我之前使用的是Django 1.10,所以我正面临着这个问题。 现在我降级到Django 1.9,它工作正常。
尝试检查你是否已经在settings.py中安装
MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',)
在模板中,数据使用csrf_token格式化:
<form>{% csrf_token %} </form>
问题似乎是,您没有正确处理GET
请求,或者直接发布数据而没有先获取表单。
当你第一次访问页面时,客户端会发送GET
请求,在这种情况下,你应该发送适当forms的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))
检查Chrome的Cookie是否设置了网站的默认选项。 允许设置本地数据(推荐)。
方法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方法可能会遇到一些响应cookies的问题。
确保在settings.py中正确configuration了django会话后端。 然后试试这个,
class CustomMiddleware(object): def process_request(self,request:HttpRequest): get_token(request)
在MIDDLEWARE_CLASSES或MIDDLEWARE下的settings.py
添加这个中间件,具体取决于django版本
get_token – 返回POST表单所需的CSRF令牌。 令牌是一个字母数字值。 如果尚未设置新标记,则会创build新标记。
我刚刚见过一次,解决办法是清空cookies。 并且可能在debuggingSECRET_KEY相关的时候被改变。
清除我的浏览器的caching为我解决了这个问题。 我曾经在本地开发环境之间进行切换,以便在发生另一个项目时处理django-blog-zinnia教程。 起初,我认为改变INSTALLED_APPS的顺序来匹配教程造成了它,但我把它们设置回来,直到清除caching才能纠正它。
在你看来你使用csrf装饰器?
from django.views.decorators.csrf import csrf_protect
@csrf_protect def view(request, params): ....