I\'m writing a webapp in Angular where authentication is handled by a JWT token, meaning that every request has an \"Authentication\" header with all the necessary informati
An alternative to the existing "fetch/createObjectURL" and "download-token" approaches already mentioned is a standard Form POST that targets a new window. Once the browser reads the attachment header on the server response, it will close the new tab and begin the download. This same approach also happens to work nicely for displaying a resource like a PDF in a new tab.
This has better support for older browsers and avoids having to manage a new type of token. This will also have better long-term support than basic auth on the URL, since support for username/password on the url is being removed by browsers.
On the client-side we use target="_blank" to avoid navigation even in failure cases, which is particularly important for SPAs (single page apps).
The major caveat is that the server-side JWT validation has to get the token from the POST data and not from the header. If your framework manages access to route handlers automatically using the Authentication header, you may need to mark your handler as unauthenticated/anonymous so that you can manually validate the JWT to ensure proper authorization.
The form can be dynamically created and immediately destroyed so that it is properly cleaned up (note: this can be done in plain JS, but JQuery is used here for clarity) -
function DownloadWithJwtViaFormPost(url, id, token) {
var jwtInput = $('').val(token);
var idInput = $('').val(id);
$('')
.attr("action", url)
.append(jwtInput)
.append(idInput)
.appendTo('body')
.submit()
.remove();
}
Just add any extra data you need to submit as hidden inputs and make sure they are appended to the form.