2014-10-29 32 views
23

Tôi đang sử dụng Django 1.7 và django-rest-framework.CSRF Không thành công: Mã thông báo CSRF bị thiếu hoặc không chính xác

tôi đã thực hiện một API trả về cho tôi một số dữ liệu JSON đặt này trong tôi settings.py

REST_FRAMEWORK = { 
    'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.AllowAny',), 
    'DEFAULT_RENDERER_CLASSES': (
    # 'rest_framework.renderers.XMLRenderer', 
    'rest_framework.renderers.JSONRenderer', 
    # 'rest_framework.renderers.BrowsableAPIRenderer', 
    ) 
} 

Khi tôi thực hiện GET cuộc gọi, nó sẽ trả cho tôi tất cả các dữ liệu, nhưng khi tôi thử với PUT/PATCH tôi nhận được:

--------Response Headers--------- 
Status Code: 403 
Date: Wed, 29 Oct 2014 18:51:42 GMT 
Vary: Cookie 
Server: WSGIServer/0.1 Python/2.7.8 
Allow: GET, POST, PUT, PATCH, HEAD, OPTIONS 
X-Frame-Options: SAMEORIGIN 
Content-Type: application/json 
--------------------------------- 

--------Response Body----------- 
{"detail": "CSRF Failed: CSRF token missing or incorrect."} 
--------------------------------- 

Điều này chỉ xảy ra khi tôi đăng nhập, nếu tôi ẩn danh tôi có thể PUT/PATCH chính xác.

Tôi đã thử với @csrf_exempt và tôi đã nhận lỗi, tôi đã bao gồm rest_framework.permissions.AllowAny trong bối cảnh ...

Tôi không có ý tưởng những gì đang xảy ra. Có ai biết vấn đề là gì không?

Trả lời

32

Khi bạn đang sử dụng SessionAuthentication, bạn đang sử dụng xác thực của Django thường yêu cầu phải kiểm tra CSRF. Django REST Framework thực thi điều này, chỉ cho SessionAuthentication, vì vậy bạn phải vượt qua mã thông báo CSRF trong tiêu đề X-CSRFToken.

Django documentation cung cấp thêm thông tin về truy xuất mã thông báo CSRF bằng jQuery và gửi yêu cầu. Mã thông báo CSRF được lưu dưới dạng cookie được gọi là csrftoken mà bạn có thể truy xuất từ ​​phản hồi HTTP, thay đổi tùy thuộc vào ngôn ngữ đang được sử dụng.

Nếu bạn không thể truy lục cookie CSRF, đây thường là dấu hiệu cho thấy bạn không nên sử dụng SessionAuthentication. Tôi khuyên bạn nên xem xét TokenAuthentication hoặc OAuth 2.0 tùy theo nhu cầu của bạn.

+1

Tôi biết tôi nên cho CSRF token khi tôi chứng thực, nhưng, thực sự tôi đang sử dụng một hình thức NET Windows Ứng dụng để giao tiếp với API này, và nó làm cho các cuộc gọi GET bằng các phương thức HTTPRequest và HTTPResponse, tôi không biết làm cách nào để có được Mã thông báo CSRF trong tình huống này, tôi không sử dụng AJAX cũng như các Biểu mẫu HTML. ** EDIT ** Ứng dụng .NET nhận văn bản thuần ở định dạng JSON và trả về cùng một số –

+0

Bạn hoàn toàn đúng, với cookie tôi có thể xử lý csrftoken và đặt nó trở lại trong dữ liệu tiêu đề, vì vậy tôi có thể tạo PUT/PATCH gọi nếu tôi đăng nhập. CẢM ƠN BẠN! –

+0

@AlexLordMordor Bạn có thể giải thích một chút về giải pháp của mình không? và lý do tại sao nó không hoạt động khi bạn là một người dùng đã đăng nhập, nhưng theo những cách mà nó hoạt động. (Tôi có chính xác cùng một vấn đề) –

0

tôi đã vấn đề tương tự, tôi đã bọc URL của tôi dưới csrf_exempt phương pháp như -

from django.views.decorators.csrf import csrf_exempt 

url(r'^api/v1/some-resource$', csrf_exempt(SomeApiView.as_view())), 
Các vấn đề liên quan