1

On a server I have several files which are protected via HTTP authentication.

Now I want to create download buttons on my HTML page to download these files. I already read that downloading a file via JavaScript/AJAX isn't possible due to security reasons. See this question.

Furthermore via an "normal" download link/button like this: <a href="..." download> it isn't possible to set the HTTP Header to provide HTTP authentication.

Is there any possibility to make a download button/link to a file with HTTP Basic authentication.

Furthermore to give a little bit more detail about my usecase, I don't want to use sessions.

Community
  • 1
  • 1
d4rty
  • 3,970
  • 5
  • 34
  • 73

2 Answers2

3

You can try the username:password syntax in the url:

<a href="username:password@example.com/file.zip">Download</a>

However, do note that browser manufacturers have started removing support for this for security reasons. IE and Chrome no longer support it.

Workaround

As a work-around, you can make the request on your server instead of directly from the HTML in the browser. Just write a simple script that accept a request and fetches the password protected file.

Here's a simple node.js example using express and request:

var express = require('express');
var request = require('request');
var app = express();

app.get('remote-file',function(req,res){
    request.get('username:password@example.com/file.zip').pipe(res);
});

app.listen(80);

Yes, the request module supports username:password syntax.

slebetman
  • 109,858
  • 19
  • 140
  • 171
  • Thank you for these approaches. But if I don't want to make requests on server side, the only option you know is the (unsopported from some browsers) `username:password` syntax? – d4rty Sep 14 '16 at 08:43
  • @d4rty: There are other approaches. One is to use java and another is to use flash. But neither will work on mobile devices and even desktop browsers are slowly phasing out support for binary plugins (Chrome for example don't support Java anymore) – slebetman Sep 14 '16 at 09:03
1

I had the same problem, the only difference is I used JWT for authentication.

However the principle still applies. You say you don't want to use sessions so this makes me think you have access to the backend.

What you can do is make a route (/generate-token) protected with auth. Here you create a token toghether with it's creation time and the requested file. Then you will have another route (/download-file/{token}), where you do the actual download based on the provided token. Notice that the second route is not auth protected.

The token can be used a single time, and only avaible for a limited number of minutes for better security.

By implementing this approach you will additionally need a table in the database and maybe a cron to regularly delete unused and expired tokens.

GabrielVasile
  • 478
  • 7
  • 7