我正在尝试将图像上传到AWS s3,但是它不起作用(底部提到了错误详细信息)。
我正在使用React和Django rest框架。
在这里,当用户上传图像时,第一个后端将使用我计划将图像上传到s3服务器的react中的signed_url来提供signed_url。
我正在使用heroku服务器,并且正在关注他们的doc
我的s3桶区域是美国东部(俄亥俄州)
到目前为止我所做的
settings.py
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME')
AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = None
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
AWS_S3_OBJECT_PARAMETERS = {
'CacheControl': 'max-age=86400',
}
urls.py
urlpatterns = [
path('api/create-permission/aws-s3/', SignS3Upload.as_view(), name='aws-s3'),
]
views.py
import os
import boto3
import mimetypes
s3 = boto3.client('s3')
class SignS3Upload(APIView):
# authentication_classes = (authentication.SessionAuthentication,)
# permission_classes = [IsAuthenticated, ]
def get(self, request):
s3_bucket = os.environ.get('AWS_STORAGE_BUCKET_NAME')
file_name = request.GET['image_name']
file_type = mimetypes.guess_type(file_name)[0]
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},
{"x-amz-algorithm": "AWS4-HMAC-SHA256"}
],
ExpiresIn=3600
)
data = {
"signed_url": presigned_post,
'url': 'https://%s.s3.amazonaws.com/%s' % (s3_bucket, file_name)
}
return Response(data)
我从后端收到的响应(Signed_url)
signed_url: {
url: 'https://my-site.s3.amazonaws.com/',
fields: {
acl: 'public-read',
'Content-Type': 'image/jpeg',
key: 'xxxxxxxxxxx.jpg',
AWSAccessKeyId: 'XX...accessKeyID...XX',
policy: 'eyJleHBpcmF0adfgdgdfgdfgd4566MjVaIiwgImNvbmRpdGlvbnMiOiBbeyJhY2wiOiAicHVibGljLXJlYWQifSwgeyJDb250ZW50LVghjhgjghZ2UvanBlZyJ9LCB7IngtYW16LWFsZ29yaXRobSI6ICJBV1M0LUhNQUMtU0hBMjU2In0sIHsiYnVja2V0IjogImRyLW5vb3IifSwgeyJrZXkiOiAieHh4eHh4eHh4eHguanBnIn1dfQ==',
signature: 'GFXgCvycTyVGjfghkUTYomevQZ0='
}
},
url: 'https://my-site.s3.amazonaws.com/xxxxxxxxxxx.jpg'
},
这是我在前端处理响应的方式
export const getSignedRequest = (image) => (dispatch, getState) => {
//alert(image.type)
const image_name = image.name
const type = image.type
axios.get('https://my-site.herokuapp.com/api/blog/api/create-permission/aws-s3/', { params: { image_name } })
.then((res) => {
dispatch({
type: GET_PARTICULAR_BLOG_IMG_UPLOAD,
payload: res.data
});
var postData = new FormData();
var key
for (key in res.data.signed_url.fields) {
postData.append(key, res.data.signed_url.fields[key]);
}
postData.append('file', image_name);
// This axios request expected to save image to s3, but its not
//working
return axios.post(res.data.signed_url.url, postData);
})
.then((res) => {
dispatch({
type: GET_PARTICULAR_BLOG_IMG_UPLOAD_AWS,
payload: res.data
});
})
.catch(err => {
//dispatch(returnErrors(err.response.data, err.response.status));
console.log(err)
dispatch({
type: GET_PARTICULAR_BLOG_IMG_UPLOAD_FAIL
});
});
};
这是我得到的错误
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>InvalidRequest</Code>
<Message>The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.</Message>
<RequestId>087F2CAF7A334FFE</RequestId>
<HostId>WyD+oGgQpPMjoIwbO1HNtweKheAsr9pV40nh1VJ+Hk+KUCXy6YsCoxA0aOjPpX+ASwy4bSesPbQ=</HostId>
</Error>