Как хранить данные на S3 и безопасный доступ пользователей к клиенту API / iOS с rails?
Я новичок в написании Rails и API. Мне нужна помощь в решении S3. Вот моя проблема.
Я пишу API для приложения iOS, где пользователи вступают в систему с API Facebook на iOS. Сервер проверяет пользователя на проблемы с токеном Facebook для пользователя iOS и выдает временный токен сеанса. С этого момента пользователю необходимо загрузить контент, который хранится в S3. Этот контент принадлежит только пользователю и подмножеству его друзей. Этот пользователь может добавить больше контента на S3, к которому можно получить доступ той же группой людей. Я думаю, это похоже на прикрепление файла к группе Facebook …
Существует два способа взаимодействия пользователя с S3: оставить его на сервере или заставить сервер выдавать временный токен S3 (не уверены в возможностях здесь), и пользователь может попасть на URL-адреса контента непосредственно на S3. Я нашел этот вопрос, говоря о подходах, однако, он действительно устарел (2 года назад): вопрос архитектуры и дизайна о загрузке фотографий с iPhone-приложения и S3
- Изменяется ли порт, когда TCP-соединение принимается сервером?
- Шаблон / алгоритм синхронизации клиент-сервер?
- Отправка строки через Bluetooth с ПК в качестве клиента на мобильный как сервер
- Отправка файлов с помощью POST с HttpURLConnection
- почему мы используем 10.0.2.2 для подключения к локальному веб-серверу вместо использования IP-адреса компьютера в Android-клиенте
Итак, вопросы:
- Есть ли способ ограничить доступ пользователя к некоторому контенту на S3 при выдаче временного токена? Как я могу это сделать? Предположим, что есть … скажем, 100 000 или более пользователей.
- Является ли хорошей идеей позволить устройству iOS напрямую вытащить этот контент?
- Или пусть сервер контролирует весь контент, проходящий (это, конечно, решает проблему)? Означает ли это, что мне нужно загрузить весь контент на сервер, прежде чем передавать его подключенным пользователям?
- Если вы знаете rails … могу ли я использовать самописцы paperclip и aws-sdk для достижения этой настройки?
Извиняюсь за несколько вопросов, и я ценю любое понимание проблемы. Благодаря 🙂
- Несколько клиентов асинхронного сервера
- close () не закрывает гнездо правильно
- Многопоточная связь Socket Client / Server
- Как запустить мое приложение в качестве суперпользователя из Eclipse?
- Каковы подводные камни использования Websockets вместо RESTful HTTP?
- API сокетов Java. Как узнать, было ли соединение закрыто?
Используя gem aws-sdk , вы можете получить временный подписанный URL-адрес для любого объекта S3, вызвав url_for
:
s3 = AWS::S3.new( :access_key_id => 1234, :secret_access_key => abcd ) object = s3.buckets['bucket'].objects['path/to/object'] object.url_for(:get, { :expires => 20.minutes.from_now, :secure => true }).to_s
Это даст вам подписанный, временный URL-адрес использования только для этого объекта в S3. Он истекает через 20 минут (в этом примере), и это полезно только для одного объекта.
Если у вас много объектов, которые нужны клиенту, вам нужно будет выпустить много подписанных URL-адресов.
Или пусть сервер контролирует весь контент, проходящий (это, конечно, решает проблему)? Означает ли это, что мне нужно загрузить весь контент на сервер, прежде чем передавать его подключенным пользователям?
Обратите внимание, что это не означает, что серверу необходимо загрузить каждый объект, ему нужно только аутентифицировать и авторизировать определенные клиенты для доступа к определенным объектам на S3.
API-документы от Amazon: https://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html#RESTAuthenticationQueryStringAuth
В приведенных выше ответах используется старый жемчуг aws-sdk-v1, а не новый aws-sdk-resources версии 2.
Новый способ:
aws_resource = Aws::S3::Resource::new aws_resource.bucket('your_bucket').object('your_object_key').presigned_url(:get, expires_in: 1*20.minutes)
где your_object_key – это путь к вашему файлу. Если вам нужно посмотреть это, вы должны использовать что-то вроде:
s3 = Aws::S3::Client::new keys = [] s3.list_objects(bucket: 'your_bucket', prefix: 'your_path').contents.each { |e| keys << e.key }
Эта информация поразительно трудно выкопать, и я почти просто сдался и использовал старый gem.
Справка
http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#presigned_url-instance_method