Django CSRF 쿠키가 설정되지 않음


85

잠시 동안 문제가 발생했습니다. CSRF 쿠키가 설정되지 않았습니다. 아래 코드를보세요

파이썬

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>

Im 붙어서 이미 쿠키를 지우고 다른 브라우저를 사용했지만 여전히 csrf 쿠키가 설정되지 않았습니다.


당신은 CsrfViewMiddleware당신의 MIDDLEWARE_CLASSES설정에 있습니까?
alecxe jul.

{%csrf_token%}템플릿에 양식을 추가 합니다.
Rohan

4
@Rohan 이미 거기에 있습니다. 질문을 참조하십시오.
alecxe jul.

1
그래, 난 이미 CsrfViewMiddleware가 있고, 난 이미 내 양식에 csrf_token이

Django cors 모듈을 사용하고 ReactJS를 통해 액세스했습니다. (둘 다 localhost에있었습니다). 나는 또한 OP 의이 문제가 있었다. 내가 추가하는 것을 나를 위해 발견 credentials: 'include': 장고의 settings.py에 추가 ALSO 다음 POST 요청과 것은 CORS_ALLOW_CREDENTIALS = True추가 할 필요없이 문제를 해결 한 것으로 보인다 @csrf_exempt뷰에. 실제로 문서에 있습니다 ... pypi.org/project/django-cors-headers-multi * 위의 질문 중 하나와 관련이 있다는 것을 알고 있지만 아직 댓글을 달 수 없으며 시간을 절약 할 수 있기를 바랍니다. 나 t 발견하는 데 걸린
DW

답변:


133

CSRF_COOKIE_SECURE = True설정되어 있고 사이트에 안전하지 않게 액세스하거나 여기여기에CSRF_COOKIE_HTTPONLY = True 명시된대로 설정된 경우에도 발생할 수 있습니다.


10
감사! 동일은 간다 SESSION_COOKIE_SECURE = True.
NonameSL 2018-08-02

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

59
보안 메커니즘을 완전히 비활성화하는 것은 오류를 수정하는 좋은 방법이 아닙니다.
Guillaume Algis

2
2017 년에 cookiecutter-django를 사용하는 경우 이것은 프로덕션에서 정답입니다.
André Duarte 2017 년

1
호기심에서 나온 이유는 무엇입니까?
Patrick Gallagher

3
이 대답은 "보안 메커니즘을 완전히 비활성화"하는 것이 아니라 CSRF 토큰을 사용할 수없는 단일 경우에만이를 수행하는 방법을 알려줍니다. 외부 클라이언트에 POST 작업을 제공해야하는 경우입니다.
mariotomo

이것은 UI에서 csrf 토큰을 제공 할 수없는 개발 단계에서 사용하는 TODO 종류의 항목입니다. 그러나 확실히 라이브 앱에는 권장되지 않습니다.
Aman Madan

24

당신이 사용하는 경우 HTML5를 API를 가져 오기 A가 사용자와 점점 기록으로 POST 요청을하기 위해 Forbidden (CSRF cookie not set.)기본적으로 있기 때문에 수, fetch페이지를로드가 아닌 다른 사용자 인 생각 장고의 결과로, 세션 쿠키를 포함하지 않는다 .

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

인스턴스화 한 Header () 메서드가 무엇인지 알 수 있습니까? 그 글로벌 자바 스크립트 방법입니까?
Abz Rockers

@AbzRockers : 예, HeadersHTML5 Fetch API의 일부인 글로벌 자바 스크립트 인터페이스입니다. developer.mozilla.org/en-US/docs/Web/API/Headers
user85461

13

에서 당신은 추가하여 해결할 수 ensure_csrf_cookie의 장식을 보기에

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

이 방법이 작동하지 않는 경우. 미들웨어에서 csrf를 주석 처리하려고합니다. 다시 테스트하십시오.


5

DRF로 작업하는 동안 비슷한 상황이 발생했으며 솔루션은 urls.py의 View에 .as_view () 메서드를 추가했습니다.


당신은뿐만 아니라 몇 가지 코드를 포함하면 좋을 것
알렉스 졸릭를

1
@AlexJolig는 방금 같은 문제에 직면했습니다. 문제는 .as_view()ApiView 를 추가하는 것을 잊었다 는 것입니다. 그래서 코드가 어떻게 생겼는지 : urlpatterns += path('resource', ResourceView)그리고 그것이 어떻게되어야하는지 : urlpatterns += path('resource', ResourceView.as_view())
Alveona

4

DRF를 사용하는 경우 urlpattern이 올바른지 확인하십시오 .as_view().

그래서 내 코드는 다음과 같이 보입니다.

urlpatterns += path('resource', ResourceView) 

다음과 같이해야합니다.

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

1

settings.py에 설치했는지 확인하십시오.

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

템플릿에서 데이터는 csrf_token으로 형식이 지정됩니다.

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

나는 당신의 모든 코드를 가지고 있지 않지만 문제가 여기에 있다고 믿습니다 .def deposit (request, account_num) : 그것을 def deposit (request) :로 변경하고 account_num을 콜백하는 방법을 찾으십시오. 이제 account_num이 테이블 필드인지 변수인지에 따라 달라집니다.
drabo2005 jul.

변수 {{account_num}}이지만 이것이 csrf 토큰에 어떤 영향을 미칩니 까?

나는 csrf 토큰이 request 만 참조했다고 믿기 때문에 여기에서 변수로 진행되는 것을 확인하거나 처리 할 수 ​​없습니다. djangoproject.com을 확인하면 csrf_token에 대한 적절한 답변을 얻을 수 있습니다.
drabo2005


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

내 오류가 사라졌습니다.


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

0

크롬의 쿠키가 웹 사이트에 대한 기본 옵션으로 설정되어 있는지 확인하십시오. 로컬 데이터 설정 허용 (권장).


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 메소드는 응답 쿠키의 문제를 일으킬 수 있기 때문입니다.


0

한 번 만났는데 해결책은 쿠키를 비우는 것입니다. 그리고 SECRET_KEY 관련 디버깅 중 변경 될 수 있습니다.


0

내 브라우저의 캐시를 지우면이 문제가 해결되었습니다. 다른 프로젝트에서 작업 한 후 django-blog-zinnia 튜토리얼을 수행하기 위해 로컬 개발 환경을 전환하고있었습니다. 처음에는 튜토리얼과 일치하도록 INSTALLED_APPS의 순서를 변경하는 것이 원인이라고 생각했지만 다시 설정하고 캐시를 지울 때까지 수정할 수 없었습니다.


0

이전에 Django 1.10을 사용하고 있었기 때문에이 문제에 직면했습니다. 이제 Django 1.9로 다운 그레이드했는데 제대로 작동합니다.


1.10.3을 사용하여이 문제가 발생했습니다. 1.10.6으로 업그레이드하면 문제가 해결되었습니다.
마이크 Darmetko

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

0

django 세션 백엔드가 settings.py에서 올바르게 구성되었는지 확인하십시오. 그럼 이걸 해봐

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

이 미들웨어를 settings.py아래 MIDDLEWARE_CLASSES또는 MIDDLEWARE장고 버전에 따라 추가하십시오.

get_token-POST 양식에 필요한 CSRF 토큰을 반환합니다. 토큰은 영숫자 값입니다. 아직 설정되지 않은 경우 새 토큰이 생성됩니다.


-4

귀하의 견해로는 csrf 데코레이터를 사용하고 있습니까 ??

from django.views.decorators.csrf import csrf_protect

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.