我正在尝试使用我的react本机应用程序通过flask服务器直接将视频上传到s3。我正在关注heroku的guide。
React Native
postVideo({className, path}) {
console.log(`posting ${className} video at ${path}`);
const vidName = path.substring(path.indexOf('/video_')+1);
return fetch(SERVER+'/sign_s3?file_name='+vidName+'&file_type=video/mp4', {
method: 'GET',
})
.then((response) => {
response.json().then((responseText)=> {
this.uploadVideo({ uri: path, name: vidName, type: 'video/mp4' }, responseText.data, responseText.url);
})
})
.catch((error) => {
console.error(error);
});
}
uploadVideo(file, s3Data, url) {
let form = new FormData();
for(key in s3Data.fields) {
form.append(key, s3Data.fields[key]);
}
console.log(s3Data);
form.append('file', file);
return fetch(url, {
method: 'PUT',
body: form,
})
.then((response) => {
console.log(response);
})
.catch((error) => {
console.error(error);
});
}
Flask服务器(环境变量存储在.env
文件中并加载)
from flask import Flask, request, jsonify
import os, boto3
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
@app.route("/sign_s3")
def sign_s3():
S3_BUCKET = os.environ.get('S3_BUCKET')
file_name = request.args.get('file_name')
file_type = request.args.get('file_type')
s3 = boto3.client('s3')
presigned_post = s3.generate_presigned_post(
Bucket = S3_BUCKET,
Key = file_name,
Fields = {"acl": "public-read", "Content-Type": file_type},
Conditions = [
{"acl": "public-read"},
{"Content-Type": file_type}
],
ExpiresIn = 3600
)
return jsonify({
'data': presigned_post,
'url': 'https://%s.s3.amazonaws.com/%s' % (S3_BUCKET, file_name)
})
if __name__ == "__main__":
app.run(host='0.0.0.0')
我设置了一个对s3具有完全访问权限的用户(它也没有使用root凭据) 用户政策(完全访问s3)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
CORS已经设置为
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
错误
<Error>
<Code>
AccessDenied
</Code>
<Message>
Access Denied
</Message>
<RequestId>
3399C78F3BD59FAF
</RequestId>
<HostId>
mTgI5xc/iz1z69NRanZ3VfAizg6PPf0s2AdC3nE1nMqDfJYlo2trMMRUmCZMusY1hJ0xBIW21Aw=
</HostId>
</Error>
如果我将存储桶设置为可公开访问,则上传有效,这让我觉得签名过程一定有问题(因为我也确定我给了用户足够的权限来访问存储区?)
答案 0 :(得分:1)
我最近也遇到了这个问题。对我来说,在将两个ACL设置都从“公开阅读”更改为“私有”后,它起作用了。