2012-07-07 25 views
22

Tôi đang cố gắng viết một trang web ở Django nơi URL API giống với URL của người dùng. Nhưng tôi đang gặp sự cố với các trang sử dụng yêu cầu POST và bảo vệ CSRF. Ví dụ: nếu tôi có trang/foo/thêm Tôi muốn có thể gửi yêu cầu POST tới trang theo hai cách:Làm cách nào để tắt tính năng bảo vệ csrf của Django chỉ trong một số trường hợp?

  1. Là người dùng cuối (được xác thực bằng cookie phiên) gửi biểu mẫu. Điều này đòi hỏi phải bảo vệ CSRF.
  2. Là ứng dụng khách API (được xác thực bằng tiêu đề yêu cầu HTTP). Điều này sẽ không thành công nếu tính năng bảo vệ CSRF được bật.

Tôi đã tìm thấy nhiều cách khác nhau để tắt CSRF, chẳng hạn như @csrf_exempt, nhưng tất cả đều vô hiệu hóa CSRF cho toàn bộ chế độ xem. Có cách nào để kích hoạt/vô hiệu hóa nó ở mức chi tiết hơn không? Hoặc tôi sẽ phải thực hiện bằng cách bảo vệ CSRF của riêng từ đầu?

+1

Bạn đã kiểm tra [tài liệu bảo vệ csrf] (https://docs.djangoproject.com/en/dev/ref/contrib/csrf/)? – machaku

+0

Tôi đã đọc các bit của nó, nhưng rõ ràng không đọc tất cả các kịch bản. Cảm ơn! – lucas

Trả lời

22

Có một phần tài liệu về Bảo vệ CSRF của Django có tiêu đề View needs protection for one path mô tả giải pháp. Ý tưởng là sử dụng @csrf_exempt trên toàn bộ chế độ xem nhưng khi tiêu đề ứng dụng khách API không có hoặc không hợp lệ, thì hãy gọi hàm được chú thích với @csrf_protect.

30

Sửa urls.py

Nếu bạn quản lý các tuyến đường của bạn trong urls.py, bạn có thể bọc đường mong muốn của bạn với csrf_exempt() để loại trừ chúng ra khỏi xác minh middleware CSRF.

ví dụ,

from django.views.decorators.csrf import csrf_exempt 
urlpatterns = patterns(
    # ... 
    # Will exclude `/api/v1/test` from CSRF 
    url(r'^api/v1/test', csrf_exempt(TestApiHandler.as_view())) 
    # ... 
) 

Ngoài ra, như một Decorator

Một số có thể tìm thấy việc sử dụng các @csrf_exempt trang trí phù hợp hơn cho nhu cầu của họ

ví dụ,

from django.views.decorators.csrf import csrf_exempt 
from django.http import HttpResponse 

@csrf_exempt 
def my_view(request): 
    return HttpResponse('Hello world') 
Các vấn đề liên quan