2013-08-20 21 views
9

Tôi đang phát triển ứng dụng DJANGO + AngularJS, trong đó phần góc không được phục vụ bởi django.Tiêu đề XSRF không được đặt trong AngularJS

tôi đặt góc $httpProvider như sau:

myApp = angular.module('myApp', []) 

myApp.config(['$httpProvider', 
    function(provider){ 
    provider.defaults.xsrfCookieName = 'csrftoken'; 
    provider.defaults.xsrfHeaderName = 'X-CSRFToken'; 
} 

Sau đó, trước khi thực hiện bất kỳ POST, tôi làm một GET mà đặt cookie. Tôi có thể khẳng định thông qua Chrome rằng cookie được thiết lập:

set-cookie:csrftoken=hg88ZZFEdLPnwDdN1eiNquA8YzTySdQO; expires=Tue, 19-Aug-2014 12:26:35 GMT; Max-Age=31449600; Path=/ 

(nó hiển thị trong tài/cookie/localhost trong các công cụ nhà phát triển Chrome)

Tuy nhiên khi tôi làm một POST, không X-CSRFToken tiêu đề đang được thiết lập

đây là POST như được ghi bởi Chrome:

POST /data/activities/search HTTP/1.1 
Host: localhost:14080 
Connection: keep-alive 
Content-Length: 2 
Accept: application/json, text/plain, */* 
Origin: http://localhost:14080 
X-Requested-With: XMLHttpRequest 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36 
Content-Type: application/json;charset=UTF-8 
Referer: http://localhost:14080/public/html/main.html?codekitCB=398694184.799418 
Accept-Encoding: gzip,deflate,sdch 
Accept-Language: en-US,en;q=0.8 
Cookie: csrftoken=hg88ZZFEdLPnwDdN1eiNquA8YzTySdQO 

Tại sao không có tiêu đề được thiết lập? Tôi nên làm gì khác để kích hoạt chức năng này?

(mặt lưu ý: nếu tôi tự vượt qua tiêu đề trong $ http() cuộc gọi, yêu cầu POST hoạt động tốt .. do đó vấn đề thực sự là tiêu đề không được thiết lập bởi AngularJS)

+0

Tôi đã sử dụng 1.0.8, nhưng tôi phát hiện ra nó chỉ có sẵn từ phiên bản 1.2.0 – luca

Trả lời

8

câu trả lời rất đơn giản: nó chỉ có sẵn từ phiên bản 1.2.0, đó là tại thời điểm một ứng cử viên phát hành.

+0

Và câu trả lời này là rất sai, bởi vì Tôi sử dụng nó trong 1.1.5. –

+0

@OZ_ Và người nói 1.1.5, nói 1.0.x :) –

+1

không, chính xác, cách tự động mới (đối tượng của câu hỏi này) chỉ từ góc 1,2, bạn đang thực hiện thủ công (có thể vẫn hữu ích) – luca

1
app.config(["$httpProvider", function($httpProvider) { 
    var csrfToken = getCookie('csrftoken'); 
    $httpProvider.defaults.headers.common['X-CSRFToken'] = csrfToken; 
}]) 

getCookie() mất từ ​​https://docs.djangoproject.com/en/dev/ref/contrib/csrf/


Hoặc thiết lập từng phương pháp riêng

$httpProvider.defaults.headers.post['X-CS.... 
$httpProvider.defaults.headers.get['X-CS.... 
5

Bản cập nhật 1.2.0 là chưa đủ đối với tôi khi sử dụng Safari hay Firefox (Chrome đã làm việc tốt mọi lúc). Vấn đề với Safari và Firefox là phụ trợ Django đã không gửi csrf-cookie trong phản hồi HTTP.

Điều tôi phải làm là thêm trang trí @ensure_csrf_cookie vào chức năng xem của tôi để tạo trang cho Angularj.

@ensure_csrf_token 
def my_view(request): 
    ... 

và trong file javascript:

myApp.config(function($httpProvider) { 
    $httpProvider.defaults.xsrfCookieName = 'csrftoken'; 
    $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken'; 
} 

Ít nhất là cho bây giờ tôi không có ý tưởng tại sao hoạt động của Chrome mà không có nó nhưng các trình duyệt khác thì không.

+0

làm thế nào để bạn nhập @ensure_csrf_token? –

+0

Uuh, tôi đoán tôi có lỗi đánh máy trong ví dụ. Đó là @ensure_csrf_cookie có thể được tìm thấy trong django.views.decorators.csrf.ensure_csrf_cookie – Janne

2

Tôi đã gặp phải sự cố tương tự và đó là lỗi của tôi.

sai lầm của tôi:

$.post('/url', data) 

Hãy chắc chắn rằng bạn đang sử dụng các đối tượng $http!

$http.post('/url', data) 

Nó rất dễ dàng để làm cho sai lầm này vì cả hai có vẻ làm việc bình đẳng cũng như nhau, ngoại trừ cựu không nhìn vào $http.defaults.headers.common['X-CSRFToken'] vv

+0

Heh. Bài đăng hay. Tôi đã không làm điều này nhưng nó cù tôi. Tuyệt vời để chia sẻ những khoảnh khắc khuôn mặt đỏ của bạn! – ErichBSchulz

1

Thay đổi góc rất thường xuyên và một số câu trả lời không hoạt động với các phiên bản mới nhất. Bằng mọi cách, kể từ góc hy vọng một tên XSRF-TOKEN cookie, và gửi một tiêu đề X-XSRF-TOKEN, chúng ta có thể cách khác đơn giản là nói với Django để sử dụng những theo mặc định:

CSRF_COOKIE_NAME = 'XSRF-TOKEN' 
CSRF_HEADER_NAME = 'HTTP_X_XSRF_TOKEN' 

Thiết lập đầu tiên (xem docs) là tên cookie cho các mã thông báo csrf, trong khi mã thứ hai (xem docs, chỉ được giới thiệu trong 1.9) là tên tiêu đề tương ứng.

ngoái, chỉ để tham khảo, đừng quên để thiết lập:

CSRF_COOKIE_HTTPONLY = False 
Các vấn đề liên quan