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.