Problema de CSRF al importar un dashboard en Superset a través de la API de Node.js.
Me estoy enfrentando al error “flask_wtf.csrf: El token de sesión CSRF falta” al intentar importar un panel de control (con “VERSIONED_EXPORT” habilitado) a través de una llamada a la API POST de NodeJS. A continuación se muestra la misma configuración que funciona para todas mis otras llamadas a la API de Superset:
const config = {
headers: {
'X-CSRFToken': await this.getCsrfToken(),
'Authorization': `Bearer ${await this.getAccessToken()}`
}
}
axios.get<t>(url, config) //o
axios.post<t>(url, data, config)
Para la llamada a la API de importación del panel de control, estoy utilizando “form-data” y funciona si agrego la importación del panel de control a “WTF_CSRF_EXEMPT_LIST”, pero quiero evitar hacer eso, aunque no funciona con todos los enfoques que he intentado:
const formData = new FormData()
// Con X-CSRFToken (mostrado arriba)
formData.append('formData', fs.createReadStream(filePath))
// Con X-CSRFToken y nombre de archivo definido y longitud
var stat = fs.statSync(filePath);
formData.append('formData', fs.createReadStream(filePath), {filename: fileName, knownLength: stat.size})
// Con X-CSRFToken y/o Referral y/o Content-Type y/o Content-Length
var stat = fs.statSync(filePath);
formData.append('formData', fs.createReadStream(filePath), {filename: fileName, knownLength: stat.size})
const contentLength = formData.getLengthSync()
const config = {
headers: {
'X-CSRFToken': await this.getCsrfToken(),
'Authorization': `Bearer ${await this.getAccessToken()}`,
'Referrer': url,
'Content-Type': 'multipart/form-data',
'Content-Length': contentLength
}
}
// Con X-XSRF-TOKEN
const config = {
headers: {
'X-XSRF-TOKEN': await this.getCsrfToken(),
'Authorization': `Bearer ${await this.getAccessToken()}`
}
}
formData.append('formData', fs.createReadStream(filePath))
await post(url, formData, config)
Sospecho que podría ser causado por “form-data”, que no puede manejar encabezados de token de CSRF, ya que puedo importar el panel de control en Postman:
Headers: {
Authorization: 'Bearer {token}',
X-CSRFToken: {csrfToken}
}
form-data: {
formData: {uploadedFile}
}
Estoy abierto a sugerencias sobre cómo puedo importar el panel de control sin utilizar “form-data” en Node.
davy.ai
Posible solución para importar un panel sin utilizar form-data en node.js
Puedes intentar usar
multipart/form-data
directamente con la cabeceraContent-Type
, en lugar de utilizar la bibliotecaform-data
. De esta manera, puedes añadir el token CSRF a las cabeceras y enviar el archivo en el cuerpo de la petición.A continuación se muestra un ejemplo de cómo puedes modificar tu código para lograr esto:
En el código anterior, estamos utilizando
FormData()
para crear una nueva instancia demultipart/form-data
. Luego, añadimos el archivo a la instancia con el nombre correcto utilizandofs.readFileSync()
. Por último, enviamos la petición con la configuración modificada.Ten en cuenta que también hemos añadido
maxContentLength
ymaxBodyLength
a la configuración para asegurarnos de que nuestra petición pueda manejar archivos grandes, yvalidateStatus
para que siempre devuelva true para cualquier código de estado HTTP.Espero que esta solución te funcione. Avísame si tienes alguna pregunta o si encuentras algún problema al implementarla.