Pattern for expiring download links

I typically build Angular 6+ SPA’s on top of service stack, authenticated using JWT and one of the common use cases I have is downloading a large file. It appears messy to try to use the SPA to download the file (I don’t want to put the file in an object, v. large), so typically just have the browser hit the api endpoint and stream directly from SS, which means I can’t add headers (I think)

I know how to roll my own expiring download token in the query string but I am wondering if there is any better pattern/feature I could use for this.

I don’t understand really what you’re trying to do, e.g. what “put the file in an object” mean, do you mean return the binary file in an API Service response and bundle with other API responses? That would be inefficient, in JSON the binary data would need to be base64 encoded. There should be a separate request to download files on their own.

Or why you would want to add headers (i.e. how do you plan to use custom HTTP as part of your downloading expiring links solution), you can return a Stream or a file info or write directly to the response in a Service and add headers as you’d normally would, the docs on Service return types and Customize HTTP Responses shows different examples of returning a File, Stream and different ways to add HTTP Headers.

So I know how to do the download, and yes it needs to be separate but also secure via a plain GET from browser- (window.open())

let me perhaps ask the question in a different way:

How can I turn a JWT into something I can put in the query string for authentication for a subsequent request? Or alternatively should I enable cookie sessions and set a cookie?

If you’re asking how you can send JWT’s on the Query String you can configure the JwtAuthProvider with:

new JwtAuthProvider {
    AllowInQueryString = true, // Allow JWT in ?ss-tok=jwt QueryString.
}

But if the JWT is configured as a Cookie then any request from the browser should already include the ss-tok JWT HTTP Cookie.

That will work, thank you!