Từ quan điểm của tôi, bạn nên sử dụng tham số POST csrf
khi gửi biểu mẫu, trong trường bị ẩn. Đây là cách duy nhất để đi.
Nhưng đối với yêu cầu AJAX, tôi khuyên bạn nên sử dụng tiêu đề X-CSRF-Token
thay thế. Chủ yếu là vì, nếu được thực hiện đúng, nó sẽ giúp bạn tiết kiệm được những rắc rối khi nhớ thêm mã thông báo cho mỗi yêu cầu POST. Hoặc, khi sử dụng các thư viện như Biểu mẫu jQuery, việc thêm các tham số POST bổ sung vào thời điểm gửi có thể trở thành hackish.
Ví dụ: nếu bạn sử dụng jQuery cho các yêu cầu AJAX của mình, nó cung cấp cho bạn a hook bạn có thể sử dụng để đặt tự động và minh bạch X-CSRF-Token
trước khi yêu cầu được thực hiện. Vì vậy, rất ít sửa đổi mã phía máy khách là bắt buộc. Và bạn tăng vọt sự khiếp sợ của mã của bạn.
-
An thực hiện ví dụ, mà tôi sử dụng thành công trên hầu như tất cả các dự án của tôi, dựa trên Django của một người, sẽ là:
jQuery(document).ajaxSend(function(event, xhr, settings) {
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function sameOrigin(url) {
// url could be relative or scheme relative or absolute
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
// Allow absolute or scheme relative URLs to same origin
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
(url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
// or any other URL that isn't scheme relative or absolute i.e relative.
!(/^(\/\/|http:|https:).*/.test(url));
}
function safeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrf.token'));
}
});
Trên server-side, bạn muốn chỉ cần đặt cookie chứa mã thông báo CSRF để khách hàng dễ dàng nhận mã thông báo. Tôi đã thay thế số app.use(express.csrf())
bằng:
app.use((function(options) {
var csrf = express.csrf(options);
return function(req, res, next) {
function onCsrfCalled() {
var token = req.session._csrf;
var cookie = req.cookies['csrf.token'];
// Define a cookie if not present
if(token && cookie !== token) {
res.cookie('csrf.token', token);
}
// Define vary header
res.header('Vary', 'Cookie');
next();
}
csrf(req, res, onCsrfCalled);
}
})());
Vâng Tôi biết điều này, nhưng tôi muốn biết điều gì tốt hơn để sử dụng: tiêu đề x-csrf-token hoặc trường ẩn? – Erik
Như bạn thấy ở đây: https://github.com/senchalabs/connect/blob/master/lib/middleware/csrf.js # L69 Express kiểm tra đầu tiên cho giá trị POST, sau đó cho giá trị chuỗi truy vấn và sau đó cho tiêu đề x-csrf-token, vì vậy tốt nhất là chuyển một trường _csrf ẩn với giá trị. – alessioalex
Tôi muốn sử dụng csrf-token trên ajax yêu cầu phương pháp tiếp cận nào tôi nên sử dụng sau đó? – Erik