Desde mi punto de vista, se debe utilizar el parámetro POST csrf
al enviar formularios, en un campo oculto. Este es el único camino a seguir.
Pero en el caso de las solicitudes AJAX, le recomendaría utilizar el encabezado X-CSRF-Token
. Principalmente porque, si se realiza correctamente, le ahorrará la molestia de recordar agregar el token para cada solicitud POST. O, al usar bibliotecas como jQuery Form, agregar parámetros POST adicionales en el momento del envío puede convertirse en un hackeo.
Por ejemplo, si utiliza jQuery para sus solicitudes AJAX, le proporciona a hook que puede usar para configurar el X-CSRF-Token
de forma automática y transparente antes de realizar la solicitud. Por lo tanto, se requiere muy poca modificación del código del lado del cliente. Y disparas la genialidad de tu código.
-
un ejemplo de implementación, que utilizo con éxito en prácticamente todos mis proyectos, basado en Django de uno, sería:
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'));
}
});
En el lado del servidor, que acababa de necesita establecer una cookie que contenga el token CSRF para que sea fácil para el cliente obtener el token. He sustituido el app.use(express.csrf())
con:
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);
}
})());
Sí lo sé, pero yo quiero saber lo que es mejor usar: un campo de cabecera X-CSRF token u oculto? – Erik
Como puede ver aquí: https://github.com/senchalabs/connect/blob/master/lib/middleware/csrf.js # L69 Express comprueba primero el valor POST, luego el valor de la cadena de consulta y luego el encabezado x-csrf-token, por lo que lo mejor sería pasar un campo _csrf oculto con el valor. – alessioalex
Quiero usar csrf-token en solicitudes ajax ¿cuál es el enfoque que debo usar entonces? – Erik