Search code examples
javascriptangularjsasp.net-web-apihttp-authentication

AngularJS + Web API - How to securely download an excel file without having to log in again


I have an application built with AngularJS and .NET Web API that uses Http Basic Authentication for security. They're on different subdomains eg: mydomain.com & api.mydomain.com

I have a secure url on the web api 'https://api.mydomain.com/downloadFile' that generates an excel file that I need to download on the client. I tried getting the file to download through angularjs using HTML5 Blob objects but kept getting 'File corrupt' error messages when the file tried to open.

The solution I came up with was to create a hidden iframe for downloading the file

<iframe style="display:none;" ng-src="{{downloadFileUrl}}"></iframe>

And setting $scope.downloadFileUrl in the controller

$scope.downloadFile = function () {
    $scope.downloadFileUrl = $sce.trustAsResourceUrl('https://api.mydomain.com/downloadFile');
};

This works but I'm forced to log in to the api again because the HTTP 'Authorization' header isn't being sent as part of the request from the iframe. Is there a way to pass the 'Authorization' header with the request from the iframe or any other way to securely download a file from the server without having to log in again?


Solution

  • I use the iframe download method as well. It seems the most solid cross-browser supported method of downloading. So I agree with your method here.

    I don't think you can pass headers, I've looked for it as well. And unless I have somehow totally missed a way of doing that (not unthinkable) I believe it just can't be done.

    I have solved this by using tickets. Here's how: whenever data is show that can be downloaded I generate a ticket on the server based on the primary key of the file to be downloaded (a guid in my case). This ticket is a simple random string of a few characters and is stored somewhere (just the db in my case). It had an expiration time of 10 minutes. Which means, clicking the download url with the ticket in the querystring will log you in automatically and start your download. The ticket expires after a absolute expiration, user explicit logout or when the download was completed successfully.

    Like so: https://api.mydomain.com/downloadFile/{fileId}?ticket=fk37cltps7