Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

1K
Visualizações
¿Cómo manejar las descargas de archivos con autenticación basada en JWT?

Estoy escribiendo una aplicación web en Angular donde la autenticación es manejada por un token JWT, lo que significa que cada solicitud tiene un encabezado de "Autenticación" con toda la información necesaria.

Esto funciona bien para llamadas REST, pero no entiendo cómo debo manejar los enlaces de descarga para archivos alojados en el backend (los archivos residen en el mismo servidor donde están alojados los servicios web).

No puedo usar enlaces regulares <a href='...'/> ya que no llevarán ningún encabezado y la autenticación fallará. Lo mismo para los diversos encantamientos de window.open(...) .

Algunas soluciones que pensé:

  1. Genere un enlace de descarga no seguro temporal en el servidor
  2. Pase la información de autenticación como un parámetro de URL y maneje manualmente el caso
  3. Obtenga los datos a través de XHR y guarde el archivo del lado del cliente.

Todo lo anterior es menos que satisfactorio.

1 es la solución que estoy usando en este momento. No me gusta por dos razones: primero, no es ideal en cuanto a seguridad, segundo, funciona pero requiere bastante trabajo, especialmente en el servidor: para descargar algo necesito llamar a un servicio que genera un nuevo "random " url, lo almacena en algún lugar (posiblemente en la base de datos) durante un tiempo y lo devuelve al cliente. El cliente obtiene la url y usa window.open o similar con ella. Cuando se solicite, la nueva URL debe verificar si aún es válida y luego devolver los datos.

2 parece al menos tanto trabajo.

3 parece mucho trabajo, incluso usando las bibliotecas disponibles, y muchos problemas potenciales. (Necesitaría proporcionar mi propia barra de estado de descarga, cargar todo el archivo en la memoria y luego pedirle al usuario que guarde el archivo localmente).

Sin embargo, la tarea parece bastante básica, así que me pregunto si hay algo mucho más simple que pueda usar.

No estoy necesariamente buscando una solución "a la manera Angular". Javascript regular estaría bien.

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Esta es una forma de descargarlo en el cliente mediante el atributo de descarga , la API de obtención y URL.createObjectURL . Obtendría el archivo usando su JWT, convertiría la carga útil en un blob, colocaría el blob en una URL de objeto, establecería la fuente de una etiqueta de anclaje en esa URL de objeto y haría clic en esa URL de objeto en javascript.

 let anchor = document.createElement("a"); document.body.appendChild(anchor); let file = 'https://www.example.com/some-file.pdf'; let headers = new Headers(); headers.append('Authorization', 'Bearer MY-TOKEN'); fetch(file, { headers }) .then(response => response.blob()) .then(blobby => { let objectUrl = window.URL.createObjectURL(blobby); anchor.href = objectUrl; anchor.download = 'some-file.pdf'; anchor.click(); window.URL.revokeObjectURL(objectUrl); });

El valor del atributo de download será el nombre final del archivo. Si lo desea, puede extraer un nombre de archivo deseado del encabezado de respuesta de disposición de contenido como se describe en otras respuestas .

over 4 years ago · Santiago Trujillo Relatório

0

Técnica

Basado en este consejo de Matias Woloski de Auth0, conocido evangelista de JWT, lo resolví generando una solicitud firmada con Hawk .

Citando a Woloski:

La forma de resolver esto es generando una solicitud firmada como lo hace AWS, por ejemplo.

Aquí tienes un ejemplo de esta técnica, utilizada para enlaces de activación.

back-end

Creé una API para firmar mis URL de descarga:

Petición:

 POST /api/sign Content-Type: application/json Authorization: Bearer... {"url": "https://path.to/protected.file"}

Respuesta:

 {"url": "https://path.to/protected.file?bewit=NTUzMDYzZTQ2NDYxNzQwMGFlMDMwMDAwXDE0NTU2MzU5OThcZDBIeEplRHJLVVFRWTY0OWFFZUVEaGpMOWJlVTk2czA0cmN6UU4zZndTOD1c"}

Con una URL firmada, podemos obtener el archivo

Petición:

 GET https://path.to/protected.file?bewit=NTUzMDYzZTQ2NDYxNzQwMGFlMDMwMDAwXDE0NTU2MzU5OThcZDBIeEplRHJLVVFRWTY0OWFFZUVEaGpMOWJlVTk2czA0cmN6UU4zZndTOD1c

Respuesta:

 Content-Type: multipart/mixed; charset="UTF-8" Content-Disposition': attachment; filename=protected.file {BLOB}

interfaz (por jojoyuji )

De esta manera, puede hacerlo todo con un solo clic de usuario:

 function clickedOnDownloadButton() { postToSignWithAuthorizationHeader({ url: 'https://path.to/protected.file' }).then(function(signed) { window.location = signed.url; }); }
over 4 years ago · Santiago Trujillo Relatório

0

Una alternativa a los enfoques existentes "fetch/createObjectURL" y "download-token" ya mencionados es un Formulario POST estándar que apunta a una nueva ventana . Una vez que el navegador lea el encabezado del archivo adjunto en la respuesta del servidor, cerrará la nueva pestaña y comenzará la descarga. Este mismo enfoque también funciona bien para mostrar un recurso como un PDF en una nueva pestaña.

Esto tiene un mejor soporte para navegadores más antiguos y evita tener que administrar un nuevo tipo de token. Esto también tendrá una mejor compatibilidad a largo plazo que la autenticación básica en la URL, ya que los navegadores eliminarán la compatibilidad con el nombre de usuario/contraseña en la URL .

En el lado del cliente, usamos target="_blank" para evitar la navegación incluso en casos de falla, lo cual es particularmente importante para las SPA (aplicaciones de una sola página).

La principal advertencia es que la validación JWT del lado del servidor debe obtener el token de los datos POST y no del encabezado . Si su marco administra el acceso a los controladores de ruta automáticamente mediante el encabezado de autenticación, es posible que deba marcar su controlador como no autenticado/anónimo para que pueda validar manualmente el JWT para garantizar la autorización adecuada.

El formulario se puede crear dinámicamente y destruir de inmediato para que se limpie correctamente (nota: esto se puede hacer en JS simple, pero JQuery se usa aquí para mayor claridad) -

 function DownloadWithJwtViaFormPost(url, id, token) { var jwtInput = $('<input type="hidden" name="jwtToken">').val(token); var idInput = $('<input type="hidden" name="id">').val(id); $('<form method="post" target="_blank"></form>') .attr("action", url) .append(jwtInput) .append(idInput) .appendTo('body') .submit() .remove(); }

Simplemente agregue cualquier dato adicional que necesite enviar como entradas ocultas y asegúrese de que se agreguen al formulario.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda