Direct Upload to S3 from the browser with Authorization Signature Ver 4
I need to upload a file to S3 directly from the browser. In the beginning I created a script that is working but to authorize I need to put my credentials accessKeyId and secretAccessKey, what it is not secure.
I figured out that I can use for authorization the "Authorization Signature"
It seems great but I can't find where I can put this authorization header to the request in the upload() method.
An example of my authorization header:
Authorization: AWS4-HMAC-SHA256 Credential=/20151016//s3/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=4eee344a71a58623febc4079024a27cb62f3d26546695422244fcefe50d0168d
Thanks for your advice.
I have found solution for this issue. My solution is based on example from this site.
In final solution I don't use javascript SDK, it is using post form with authorization inputs what is sending with post parameters.
You can enclose a signed policy document with your POST request in order to authenticate securely, with AWS Signature Version 4.
If you're on Node, you can use the aws-s3-form package on the server to generate the necessary form data your client requires in order to send a successful request to S3.
You might want to read my blog post on the subject for full insight.
Example Server Side Code (Node)
let AwsS3Form = require('aws-s3-form')
[...]
// A hapi.js server route
server.route({
method: ['GET',],
path: '/api/s3Settings',
config: {
auth: 'session',
handler: (request, reply) => {
let {key,} = request.query
let keyPrefix = `u/${request.auth.credentials.username}/`
let region = process.env.S3_REGION
let s3Form = new AwsS3Form({
accessKeyId: process.env.AWS_ACCESS_KEY,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
region,
bucket,
keyPrefix,
successActionStatus: 200,
})
let url = `https://s3.${region}.amazonaws.com/${bucket}/${keyPrefix}${key}`
let formData = s3Form.create(key)
reply({
bucket,
region,
url,
fields: formData.fields,
})
},
},
})
Example Client Side Code
let R = require('ramda')
let ajax = require('./ajax')
class S3Uploader {
constructor({folder,}) {
this.folder = folder
}
send(file) {
let key = `${this.folder}/${file.name}`
return ajax.getJson(`s3Settings`, {key,})
.then((s3Settings) => {
let formData = new FormData()
R.forEach(([key, value,]) => {
formData.append(key, value)
}, R.toPairs(s3Settings.fields))
formData.append('file', file)
return new Promise((resolve, reject) => {
let request = new XMLHttpRequest()
request.onreadystatechange = () => {
if (request.readyState === XMLHttpRequest.DONE) {
if (request.status === 200) {
resolve(s3Settings.url)
} else {
reject(request.responseText)
}
}
}
let url = `https://s3.${s3Settings.region}.amazonaws.com/${s3Settings.bucket}`
request.open('POST', url, true)
request.send(formData)
})
}, (error) => {
throw new Error(`Failed to receive S3 settings from server`)
})
}
}
链接地址: http://www.djcxy.com/p/39036.html