The form template
<title>S3 POST Form</title> <form action="https://.s3.amazonaws.com/" enctype="multipart/form-data" method="post"> <input name="key" type="hidden" value="uploads/${filename}" /> <input name="AWSAccessKeyId" type="hidden" value="" /> <input name="acl" type="hidden" value="public-read" /> <input name="success_action_redirect" type="hidden" value="http://example.com" /> <input name="policy" type="hidden" value="" /> <input name="signature" type="hidden" value="" /> File to upload to S3: <input name="file" type="file" /> <input type="submit" value="Upload File to S3" /> </form>
The python code
from django.http import HttpResponseBelow: You can find your keys at https://aws-portal.amazon.com/gp/aws/securityCredentials. The aws access key is public and will be sent to the client. The secret access key is used to calculate a signuature for the policy json.
from django.template import loader, Context
import base64
import hmac, sha
def upload(request):
t = loader.get_template("upload.html")
vars = {}
policy = base64.b64encode(policy_json)
aws_secret_key = "SEE BELOW"
signature = base64.b64encode(hmac.new(aws_secret_key, policy, sha).digest())
vars["signature"] = signature
vars["policy"] = policy
vars["aws_access_key"] = "SEE BELOW"
vars["bucket"] = "your-bucket"
return HttpResponse(t.render(Context(vars)))
policy_json = """
{"expiration": "2013-01-01T00:00:00Z",
"conditions": [
{"bucket": "your-bucket"},
["starts-with", "$key", "uploads/"],
{"acl": "public-read"},
{"success_action_redirect": "http://example.com"},
["content-length-range", 0, 1048576]
]
}
"""
Make sure to replace "your-bucket" with the name of your bucket. It should work now.
A problem I ran into
Initially I got this error:The request signature we calculated does not match the signature you provided. Check your key and signing method.That was because I had the json in my policy field, but actually it should contain the base64-encoded json.