Я использую DRF для хранения загруженных пользователем изображений на S3, и на S3 я вижу, что изображения доступны для общественности с помощью URL.
Мое беспокойство здесь заключается в том, что существует какой-либо лучший способ обеспечить этоизображения и ограничить их для владельца этого изображения только для его просмотра.
Я использую Heroku для развертывания моей DRF API Framework, но я вижу это как проблему безопасности для моего пользователя, который загружает файлы изображений в S3bucket.
Я пытаюсь изолировать изображения пользователей по их именам. Это само собой. Но все же это общедоступно, поэтому я могу получить доступ к этим изображениям для другого пользователя, просто выясни это там по имени.
ВотS3 URL для медиа-изображений
https://xxx.s3.amazonaws.com/media/persons/niravjoshi/20181218152410.jpg
Вот мой settings.py для Django
import os
import pymysql # noqa: 402
pymysql.install_as_MySQLdb()
import dj_database_url
from decouple import config
import django_heroku
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
#SECRET_KEY = 'feufm)u(pvsvb%&_%%*)p_bpa+sv8zt$#_-do5q3(vou-j*d#p'
SECRET_KEY = config('SECRET_KEY')
DEBUG = config('DEBUG', default=False, cast=bool)
DATABASES = {
'default': dj_database_url.config(
default=config('DATABASE_URL')
)
}
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
#Django Project Apps
'persons',
'rest_framework',
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.google',
#'social_django',
]
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
AWS_REGION = os.environ.get('AWS_REGION', '') # e.g. eu-west-1
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY', '')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_KEY', '')
AWS_STORAGE_BUCKET_NAME = os.environ.get('S3_BUCKET', '')
AWS_QUERYSTRING_AUTH = False
AWS_S3_CUSTOM_DOMAIN = os.environ.get("AWS_S3_CUSTOM_DOMAIN", "")
MEDIAFILES_LOCATION = 'media'
DEFAULT_FILE_STORAGE = 'DjangoE2ISAapi.storage_backends.MediaStorage'
MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION)
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
AWS_STATIC_LOCATION = 'static'
STATICFILES_STORAGE = 'DjangoE2ISAapi.storage_backends.StaticStorage'
STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, AWS_STATIC_LOCATION)
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
django_heroku.settings(locals())
from DjangoE2ISAapi.restconf.main import *
Вот мой storage_backends.py
from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage
class StaticStorage(S3Boto3Storage):
location = settings.AWS_STATIC_LOCATION
class MediaStorage(S3Boto3Storage):
location = settings.MEDIAFILES_LOCATION
Вот моя личность model.py.
from django.core.serializers import serialize
from django.db import models
from django.conf import settings
import json
from django.core.serializers.json import DjangoJSONEncoder
# Create your models here.
def upload_file(instance,filename):
import os
from django.utils.timezone import now
filename_base, filename_ext = os.path.splitext(filename)
return "persons/{user}/{filename}".format(user=instance.UserName, filename=now().strftime("%Y%m%d%H%M%S")+filename_ext.lower())
class PersonQuerySet(models.QuerySet):
def serialize(self):
list_values=list(self.values('UserName','PersonId','PersonName','Person_Image','Person_sex','Person_BDate'))
print (list_values)
return json.dumps(list_values,sort_keys=True,indent=1,cls=DjangoJSONEncoder)
class PersonManager(models.Manager):
def get_queryset(self):
return PersonQuerySet(self.model,using=self._db)
class Person(models.Model):
UserName = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,)
PersonId = models.AutoField(primary_key=True)
PersonName = models.CharField("person's first name", max_length=30,null=False)
Person_Image = models.ImageField(upload_to=upload_file,null=True, blank=True)
SEX = (('M','Male'),('F','Female'), ('N','None'), )
Person_sex = models.CharField(max_length=1,choices=SEX,null=False)
Person_BDate = models.DateField(null=False)
Person_CDate = models.DateField(null=False,auto_now_add=True)
objects = PersonManager()
def __str__(self):
return str(self.PersonName) or ""
def serialize(self):
data={
'UserName': self.UserName,
'PersonId': self.PersonId,
'PersonName': self.PersonName,
'Person_Image':self.Person_Image,
'Person_sex': self.Person_sex,
'Person_Bdate': self.Person_BDate
}
data = json.dumps(data,sort_keys=True,indent=1,cls=DjangoJSONEncoder)
return data
@property
def owner(self):
return self.UserName
Здесьответ Person API View: