簡體   English   中英

從 Django Web 應用程序刪除 AWS S3 對象時出錯

[英]Error deleting AWS S3 objects from Django Web App

當我嘗試從 Python/Django Webapp 中刪除 S3 文件時出現以下錯誤。

ClientError at /eq83/deletephoto
An error occurred (AccessDenied) when calling the DeleteObject operation: Access Denied

我查看或上傳文件沒有問題。

桶權限的一些細節

所有block public access框都未選中。

Bucket policy為空,並No policy to display.

訪問控制列表 (ACL) 已選中bucket owner的所有框,並且未選中 rest。

這就是跨域資源共享(CORS)

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "POST",
            "PUT",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]

我的申請的一些細節

以下是我的settings.py文件的摘錄。 我已經屏蔽了密鑰並省略了 TEMPLATES、MIDDLEWARE 和一些 INSTALLED_APPS


import os
import dotenv
dotenv.read_dotenv()

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'

DEBUG = True

ALLOWED_HOSTS = ["*"]


INSTALLED_APPS = [
'tracker.apps.TrackerConfig',
...
'storages'
]

WSGI_APPLICATION = 'tracker_django.wsgi.application'


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

STATIC_URL = '/static/'

STATICFILES_DIRS = [os.path.join(BASE_DIR,'tracker', 'static')]

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY', '')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_KEY', '')

AWS_STORAGE_BUCKET_NAME = 'tracker-django-files'

AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = "public-read"

AWS_QUERYSTRING_AUTH = False

這是我如何刪除views.py中的文件的示例。

def remove_eq_files(request, file_id):
    try:
        eq_file = EqFile.objects.get(pk=file_id)
        eq_id=eq_file.eq.id
    except KeyError:
        return render(request, "jobs/error.html", {"message": "No Selection"})
    except EqFile.DoesNotExist:
        return render(request, "jobs/error.html", {"message": "Invalid File Selection. Contact Admin"})
    #delete file in S3
    eq_file.eq_file.delete(save=False) 
    #delete file in django
    eq_file.delete() 
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

最后,這是來自models.py文件的代碼片段


class Eq(models.Model):
    name = models.CharField(max_length=128, blank=False)

def eq_file_path(instance, filename):
    try:
        eq=instance.eq
        path= "eq/"+eq.name +"_"+str(eq.pk)+"/eq_folder/"+filename
        return path

class EqFile(models.Model):
    eq_file=models.FileField(max_length=500, null=True, blank = True, upload_to = eq_file_path)
    file_url=models.URLField(max_length=500, null=True, blank=True)
    file_name = models.CharField(max_length=256, null=True, blank=True)
    eq= models.ForeignKey(Eq, null=True, on_delete=models.CASCADE, blank=True, related_name="eq_file")
    def filename(self):
        return os.path.basename(self.model_file.name)

我有一個更有經驗的人設置了 s3 並幫助我集成它,並且已經運行了一年多,包括刪除對象,我想我上次測試是在 4 周前左右。 我發現刪除似乎不再起作用很奇怪,並認為亞馬遜可能改變了刪除 s3 對象的工作方式。 或者也許我無意中更改了 Python 方面的一些代碼並將其搞砸了。

(請注意,客戶尚未使用此軟件,我知道這些設置可能不適合部署。)

任何幫助將不勝感激!

我最終實施的一種解決方案是設置一個 IAM 用戶,授予該 IAM 編輯存儲桶的權限,然后將 IAM 憑證添加到程序中。

設置 IAM

  1. 打開 AWS 控制台,使用搜索欄打開“IAM”
  2. select 左側“訪問管理”下的“用戶”並創建一個新的 IAM 用戶。 重要提示:將安全憑證(訪問密鑰和密鑰)保存在某處並保存用戶 ARN
  3. 單擊右側的“+添加內聯策略”並使用以下代碼創建一個新策略,除了替換BUCKETS!!! 使用您的存儲桶的名稱。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:ListBucketVersions",
                "s3:GetBucketLocation",
                "s3:Get*",
                "s3:Put*",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::BUCKETS!!!",
                "arn:aws:s3:::BUCKETS!!!/*"
            ]
        }
    ]
}

授予 IAM 編輯存儲桶的權限

  1. 在 AWS 打開 S3(通過搜索欄或菜單)並單擊左側的存儲桶
  2. 單擊要修改的存儲桶,然后單擊“權限”選項卡
  3. 向下滾動到“存儲桶策略”,點擊編輯,然后粘貼下面的代碼,除了替換USERARN!!! 使用您之前在 IAM 管理控制台中保存的用戶 ARN 並替換BUCKETS!!! 使用您的存儲桶的名稱。
{
    "Version": "2012-10-17",
    "Id": "Policy1488494182833",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "USERARN!!!"
            },
            "Action": [
                "s3:ListBucket",
                "s3:ListBucketVersions",
                "s3:GetBucketLocation",
                "s3:Get*",
                "s3:Put*",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::BUCKETS!!!",
                "arn:aws:s3:::BUCKETS!!!/*"
            ]
        }
    ]
}

現在任何擁有 IAM 登錄憑證的人都可以操作存儲桶。

將 IAM 憑證添加到程序中。

由於我的項目是 Django 項目,所以我使用的是 boto3,我在settings.py中輸入了憑據,只需添加下面的數據,除了替換AK!!! 使用您之前保存的訪問密鑰和SK!!! 使用您之前保存的秘密訪問密鑰。

AWS_ACCESS_KEY_ID = 'AK!!!'
AWS_SECRET_ACCESS_KEY = 'SK!!!'

如果你不使用 Django 框架,我不知道你會怎么做。

感謝 luk2302 提示您設置 IAM 用戶。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM