Hi JMAPers,
At Linagora we're making good progress on our JMAP implementation, currently completing the "attachments" part.
I'd like to raise a concern regarding the specification about attachments download (important part in bold):
downloadUrl: String The URL endpoint to use when downloading files, in RFC6570 URI Template (level 1) format. The URL MUST contain a variable called blobId. The URL SHOULD contain a variable called name. The client may use this template in combination with a blobId to download any binary data (files) referenced by other objects. Since a blob is not associated with a particular name, the template SHOULD allow a name to be substituted in as well; the server will return this as the filename if it sets a Content-Disposition header. To download the data the client MUST make an authenticated GET request (see below for how to authenticate requests) to the expanded URL, and then follow any redirects.
While this is perfectly fine, it is really not friendly to a client implementation running in a browser (as we currently do) because you can't change sent headers when using native browser tools (a link, a call to window.open, etc.) for file downloads. Workarounds include crappy solutions, amongst them:
- Switch to a cookie-based authentication (booooh !)
- Proxy the download request through any backend capable of setting request headers
- Download the file using an Ajax request then
asks the user to download a manually-created Blob (really not scalable)
I have a proposal to enrich the spec on this part to allow easy file downloads inside a browser (keeping the authentication on the download endpoint) but I'd like to hear from other implementers about that. How do you do it when running inside a browser?
My proposal would be to amend the spec to propose a signing mechanism for attachment download requests, very similar to what Amazon is doing on the AWS API. The process is as follows:
- The client makes an authenticated POST to the interpolated downloadUrl (with all available variables substituted).
- The server replies with a crafted "token". This token has a very short expiration time, and expires as soon as it is used.
- The client downloads the file using an unauthenticated GET request, passing the token in the query String.
WDYT?
Regards,
David