Django CSRF Cookie chưa được đặt


85

Tôi gặp một số vấn đề trong một thời gian, tôi đang gặp phải CSRF Cookie chưa được thiết lập. Vui lòng xem các mã bên dưới

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

Trong HTML, đây là mã

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>

Tôi bị kẹt, tôi đã xóa cookie, sử dụng trình duyệt khác nhưng vẫn chưa đặt cookie csrf.


Bạn có CsrfViewMiddlewaretrong MIDDLEWARE_CLASSEScài đặt của mình không?
alecxe

Thêm {%csrf_token%}vào biểu mẫu của bạn trong mẫu.
Rohan

4
@Rohan nó đã ở đó rồi, xem câu hỏi.
alecxe

1
Yup, tôi đã có CsrfViewMiddleware, và tôi đã có csrf_token trong hình thức của tôi

Tôi đang sử dụng mô-đun Django cors và truy cập nó thông qua ReactJS. (Cả hai đều trên localhost). Tôi cũng có vấn đề này của OP. Tôi thấy rằng việc thêm credentials: 'include'vào yêu cầu ĐĂNG và sau đó CŨNG thêm vào settings.py: của django CORS_ALLOW_CREDENTIALS = Truedường như đã khắc phục được sự cố mà không cần thêm @csrf_exemptvào chế độ xem. Nó thực sự nằm trong tài liệu ... pypi.org/project/django-cors-headers-multi * Tôi biết điều này liên quan đến một trong những câu hỏi ở trên nhưng tôi chưa thể bình luận và tôi muốn hy vọng sẽ giúp ai đó tiết kiệm thời gian. đưa tôi đi tìm t
DW

Câu trả lời:


133

Điều này cũng có thể xảy ra nếu CSRF_COOKIE_SECURE = Trueđược đặt và bạn đang truy cập trang web không an toàn hoặc nếu CSRF_COOKIE_HTTPONLY = Trueđược đặt như đã nêu ở đâyở đây


10
Cảm ơn! Cũng vậy SESSION_COOKIE_SECURE = True.
NonameSL

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
Vô hiệu hóa hoàn toàn cơ chế bảo mật không phải là một cách tốt để sửa lỗi.
Guillaume Algis

2
Nếu bạn đang sử dụng cookiecutter-django vào năm 2017 thì đây là câu trả lời chính xác trong sản xuất.
André Duarte

1
Tại sao vậy, vì tò mò?
Patrick Gallagher

3
Câu trả lời này không đề xuất "vô hiệu hóa hoàn toàn cơ chế bảo mật", nó chỉ cho biết cách thực hiện điều đó đối với một trường hợp duy nhất mà bạn có thể không sử dụng được mã thông báo CSRF. Đây là trường hợp của tôi, nơi tôi cần cung cấp hành động ĐĂNG cho khách hàng bên ngoài.
mariotomo

Đây là loại vật phẩm CẦN LÀM mà tôi sử dụng trong giai đoạn phát triển, khi bạn không thể cung cấp mã thông báo csrf từ giao diện người dùng. Nhưng chắc chắn không được khuyến khích cho một ứng dụng trực tiếp.
Aman Madan

24

Nếu bạn đang sử dụng API tìm nạp HTML5 để thực hiện yêu cầu ĐĂNG với tư cách là người dùng đã đăng nhập và nhận được Forbidden (CSRF cookie not set.), có thể do theo mặc định fetchkhông bao gồm cookie phiên, dẫn đến việc Django nghĩ rằng bạn là người dùng khác với người đã tải trang .

Bạn có thể bao gồm mã thông báo phiên bằng cách chuyển tùy chọn credentials: 'include'để tìm nạp:

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

tôi có thể biết phương thức Header () mà bạn đã khởi tạo là gì không? đó là phương pháp javascript toàn cục?
Abz Rockers

@AbzRockers: Có, Headerslà giao diện javascript toàn cầu, một phần của API tìm nạp HTML5. developer.mozilla.org/en-US/docs/Web/API/Headers
user85461 28/02/18

13

Từ điều này, bạn có thể giải quyết nó bằng cách thêm trình trang trí ensure_csrf_cookie vào chế độ xem của bạn

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

nếu phương pháp này không hoạt động. bạn sẽ cố gắng bình luận csrf trong phần mềm trung gian. và kiểm tra lại.


5

Tôi đã gặp trường hợp tương tự khi làm việc với DRF, giải pháp là thêm phương thức .as_view () vào Chế độ xem trong urls.py


Sẽ tốt hơn nếu bạn cũng bao gồm một số mã
Alex Jolig

1
@AlexJolig vừa phải đối mặt với vấn đề tương tự, vấn đề là tôi đã quên thêm .as_view()ApiView sau khi đăng ký của mình Vì vậy, mã trông như thế nào: urlpatterns += path('resource', ResourceView)Và đó là cách nó phải như thế này: urlpatterns += path('resource', ResourceView.as_view())
Alveona

4

Nếu bạn đang sử dụng DRF, hãy kiểm tra xem urlpatterns của bạn có đúng không, có thể bạn đã quên .as_view():

Vì vậy, mã của tôi trông như thế nào:

urlpatterns += path('resource', ResourceView) 

Và đó là cách nó phải như thế này:

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

1

thử kiểm tra xem bạn đã cài đặt trong settings.py

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

Trong mẫu, dữ liệu được định dạng bằng csrf_token:

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

Tôi không có tất cả mã của bạn nhưng tôi tin rằng vấn đề là ở đây: def ký gửi (request, account_num): đã đổi nó thành def ký gửi (request): và tìm cách gọi lại account_num. bây giờ nó sẽ phụ thuộc nếu account_num là một trường bảng hay một biến.
drabo2005

Đây là một biến {{account_num}}, nhưng điều này ảnh hưởng đến mã thông báo csrf như thế nào?

tôi tin rằng mã thông báo csrf chỉ tham chiếu đến yêu cầu, vì vậy nó không thể xác minh hoặc xử lý những gì xảy ra với biến ở đây. kiểm tra djangoproject.com có ​​thể bạn sẽ nhận được câu trả lời thích hợp về csrf_token.
drabo2005


1

Điều này cũng xảy ra khi bạn không đặt hành động biểu mẫu.
Đối với tôi, nó đã hiển thị lỗi này khi mã là:

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

Khi tôi sửa mã của mình thành cái này:

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

lỗi của tôi đã biến mất.


0

Có vẻ như vấn đề là bạn không xử lý GETcác yêu cầu một cách thích hợp hoặc đăng trực tiếp dữ liệu mà không nhận được biểu mẫu trước.

Khi bạn truy cập trang lần đầu, khách hàng sẽ gửi GETyêu cầu, trong trường hợp đó bạn nên gửi html với hình thức phù hợp.

Sau đó, người dùng điền vào biểu mẫu và gửi POSTyêu cầu với dữ liệu biểu mẫu.

Chế độ xem của bạn phải là:

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

Kiểm tra xem cookie của chrome có được đặt với tùy chọn mặc định cho các trang web hay không. Cho phép dữ liệu cục bộ được thiết lập (khuyến nghị).


0

Phương pháp 1:

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

Phương pháp 2:

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

Bởi vì phương thức render_to_response có thể gặp một số vấn đề với cookie phản hồi.


0

Tôi mới gặp một lần, giải pháp là làm trống cookie. Và có thể được thay đổi trong khi gỡ lỗi liên quan đến SECRET_KEY.


0

Xóa bộ nhớ cache của trình duyệt đã khắc phục sự cố này cho tôi. Tôi đã chuyển đổi giữa các môi trường phát triển cục bộ để thực hiện hướng dẫn django-blog-zinnia sau khi làm việc trên một dự án khác khi nó xảy ra. Lúc đầu, tôi nghĩ rằng việc thay đổi thứ tự của INSTALLED_APPS để phù hợp với hướng dẫn đã gây ra lỗi này, nhưng tôi đã đặt lại những thứ này và không thể sửa nó cho đến khi xóa bộ nhớ cache.


0

Tôi đã sử dụng Django 1.10 trước đây, vì vậy tôi đang gặp phải vấn đề này. Bây giờ tôi đã hạ cấp nó xuống Django 1.9 và nó đang hoạt động tốt.


Sử dụng 1.10.3, tôi gặp sự cố này. Nâng cấp lên 1.10.6 đã khắc phục sự cố cho tôi.
Mike Darmetko

0

Tôi đã gặp lỗi tương tự, trong trường hợp của tôi, việc thêm method_decorator sẽ giúp:

from django.views.decorators.csrf import csrf_protect
from django.utils.decorators import method_decorator

method_decorator(csrf_protect)
def post(self, request):
    ...

0

Đảm bảo chương trình phụ trợ phiên django của bạn được định cấu hình đúng cách trong settings.py. Sau đó, hãy thử điều này,

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

Thêm phần mềm trung gian này vào settings.pybên dưới MIDDLEWARE_CLASSEShoặc MIDDLEWAREtùy thuộc vào phiên bản django

get_token - Trả về mã thông báo CSRF cần thiết cho biểu mẫu POST. Mã thông báo là một giá trị chữ và số. Mã thông báo mới được tạo nếu chưa được đặt.


-4

Theo quan điểm của bạn, bạn có đang sử dụng trình trang trí csrf không ??

from django.views.decorators.csrf import csrf_protect

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.