通过django s3中间件保存文件时获取Http403(但可以在shell中使用boto进行保存) [英] Getting Http403 when saving files through django s3 middleware (but can save using boto in shell)

查看:82
本文介绍了通过django s3中间件保存文件时获取Http403(但可以在shell中使用boto进行保存)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图通过django应用程序将用户上传的文件保存到s3存储桶中.我正在使用 django-s3-storage 中间件,但是我一直在获取:

I have been trying to save user uploaded files to my s3 bucket via my django application. I'm using the django-s3-storage middleware, but I keep getting:

S3ResponseError:禁止403(访问被拒绝)

S3ResponseError: 403 Forbidden (Access Denied)

我正在使用以下设置:

MEDIAFILES_LOCATION = 'media'
AWS_S3_CUSTOM_DOMAIN = 'my-bucket.s3-website-eu-west-1.amazonaws.com'
AWS_S3_HOST = 's3-website-eu-west-1.amazonaws.com'
MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION)
DEFAULT_FILE_STORAGE = 'django_s3_storage.storage.StaticS3Storage'

#S3 settings from https://github.com/etianen/django-s3-storage
AWS_ACCESS_KEY_ID = "xxx"
AWS_SECRET_ACCESS_KEY = "yyy"
AWS_S3_BUCKET_NAME = "my-bucket"
AWS_S3_CALLING_FORMAT = "boto.s3.connection.OrdinaryCallingFormat"

# Make user uploaded files public
AWS_S3_BUCKET_AUTH = False
AWS_S3_MAX_AGE_SECONDS = 60*60*24*365 # 1 year
AWS_S3_GZIP = True

我知道凭据是有效的:

from boto.s3.connection import S3Connection
from django.conf import settings
conn = S3Connection(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY)
b = conn.get_bucket('my-bucket')
key = b.get_key('test.txt')
print(key.get_contents_as_string())
>>>this is a test
from boto.s3.key import Key
k = Key(b)
k.key = 'test2.txt'
k.set_contents_from_string('another test')
>>>12

我也设置了一个完全开放的CORS策略(同时试图从我的开发机上使之工作):

I've set a completely open CORS policy too (while trying to get this working from my dev machine):

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

那是什么阻止我通过中间件进行身份验证? (或者是什么原因导致了403?)

So what's stopping me authenticating via the middleware? (Or what else could be causing the 403?)

存储桶策略,允许访问存储桶my-bucket的IAM用户production.我删除了用户ARN数字,并替换为x.

bucket policy allowing access to IAM user production for bucket my-bucket. I've removed the user ARN digits and replaced with x.

{
    "Version": "2016-12-30",
    "Statement": [
        {
            "Sid": "PublicReadForGetBucketObjects",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::my-bucket/*"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::xxxxxxxxxxxx:user/production"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::my-bucket",
                "arn:aws:s3:::my-bucket/*"
            ]
        }
    ]
}

根据此错误,该错误不是签名错误.我使用的是Django 1.10,Boto 2.45,django-s3-storage 0.9.11.

The error is not a signature error as per this bug. I'm on django 1.10, boto 2.45, django-s3-storage 0.9.11.

S3ResponseError at /the-url/

S3ResponseError: 403 Forbidden
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message>

好,发生了一件奇怪的事情(我不记得在设置中进行了任何更改以导致此问题):我上传了一个文件,没有错误返回.该文件按照模型定义image0 = models.ImageField(upload_to="product_images")保存.然后可以在https://s3.amazonaws.com:443/productimages/myimage.jpg上找到该文件(嗯?为什么?).在http://my-bucket.s3-website-eu-west-1.amazonaws.com/media/productimages/myimage.jpg 可用,在我的存储桶的media/productimages/myimage.jpg中也不可见.

Edit 2:

OK, this weird thing happened (I don't recall having changed anything in the settings to cause this): I upload a file, and no error is returned. The file is saved as per the model definition image0 = models.ImageField(upload_to="product_images"). The file is then available at https://s3.amazonaws.com:443/productimages/myimage.jpg (huh? why?). It is not available at http://my-bucket.s3-website-eu-west-1.amazonaws.com/media/productimages/myimage.jpg, nor is it visible in my bucket's media/productimages/myimage.jpg.

所以看来s3或中间件正在发生一些有趣的事情.有什么想法吗?

So it seems that something funny is going on with either s3 or the middleware. Any ideas?

推荐答案

使用描述的存储桶此处.您的存储桶名称是否符合DNS?

Using bucket described here. There are two access methods - path, and virtual hosted. More on that here. Is your bucket name is DNS compliant?

这篇关于通过django s3中间件保存文件时获取Http403(但可以在shell中使用boto进行保存)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆