Using presigned URLs, you can allow a browser to download a private file directly from S3 without exposing your S3 credentials to the user. The following is an annotated example of how this can be used in a Node.js application, using minio-js.
This application will work out of the box, just copy each piece together into a file and run it.
const Minio = require('minio')
var client = new Minio.Client({
endPoint: 'play.minio.io',
port: 9000,
secure: true,
accessKey: 'Q3AM3UQ867SPQQA43P2F',
secretKey: 'zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG'
})
In order to sign the request, we need to create the Minio client and pass it our credentials. With the client, you can download and upload files, among much more.
These are real credentials to an example Minio server — try it out!
// express is a small HTTP server wrapper, but this works with any HTTP server
const server = require('express')()
server.get('/presignedUrl', (req, res) => {
client.presignedGetObject('pictures', 'house.png', (err, url) => {
if (err) throw err
res.redirect(url)
})
})
server.listen(8080)
presignedGetObject
creates the URL we can use to download pictures/house.png
. The link will
automatically expire after 7 days — this can be adjusted using the optional
expiry
argument.
In this example, the HTTP server will generate a link to download an image of a house from S3. It will then redirect the user to that link.
You can also use client-side JavaScript to request the file from the server.
Using jQuery, here is an example of this in action. It
will insert some text from S3 into a div
.
<div id="response"></div>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script defer type="text/javascript">
$.get('http://YOUR_SERVER:8080/presignedUrl', (text) => {
// Set the text.
$('#response').text(text)
}, 'string')
</script>