【问题标题】:Rails: Best way to allow users to upload images to either a Dropbox linked folder or "our" storage on Amazon S3Rails:允许用户将图像上传到 Dropbox 链接文件夹或 Amazon S3 上“我们的”存储的最佳方式
【发布时间】:2017-10-04 00:09:53
【问题描述】:
我正在开发一个用户加入“流”的项目。在流设置期间,创建流的人(流创建者)可以选择:
- 将会员添加到信息流中的所有照片上传到我们的托管解决方案 (S3)
- 将成员添加到流中的所有照片上传到流创建者自己的 Dropbox 认证文件夹中
将来我想添加更多存储提供商(例如 Drive、Onesky 等)
关于如何解决这个问题,我有几个不同的问题。
- 照片数据库中的结构应该是什么?我目前只有 photo_url,但是从数据的角度来看,使用预签名的 url 以及上传照片的不同方式(s3、Dropbox 等)并不容易管理
- 应如何存储每个存储提供程序的访问令牌?请记住,只会存储流创建者的 access_token,并且流中的每个人都将在上传照片时共享该令牌
- 以后我会添加 iOS 和 Web 客户端,它们会直接上传到存储提供商并绕过服务器以避免服务器负载过重
【问题讨论】:
标签:
ruby-on-rails
amazon-s3
【解决方案1】:
我们设置了很多带有不同类型文件存储的 Rails 应用程序。
是的,只是一个 url 在未来是不可管理的。为了节省大量时间,您可以使用像 carrierwave 或 paperclip 这样的 gem。他们处理所有缩略图生成和文件验证。一种方法是,您可以将文件从客户端直接上传到 S3 或 Dropbox 到 tmp 文件夹,然后告诉您的 Rails 应用“嘿,这是新上传文件的 url”,回形针和carrierwave 会处理缩略图生成和存储。 (Example for paperclip)
不知道你的流是如何工作的,所以我不能给出一个好的答案-.-
使用我在 1 中提到的设置,您应该从不同的客户端直接上传到 S3 或 Dropbox 等,上传后,客户端告诉 Rails 后端它应该从该 url 导入文件。 (在回形针或carrierwave完成处理之前,您可以使用文件中的tmp url直接在您的流中显示某些内容)
【解决方案2】:
就数据库存储而言,您的应用程序应根据您呈现给用户和流的接口来规定结构。
如果您有用户上传照片并且他们无法选择 URI,并且您在流中没有任何层次结构,那么我建议您在主照片表中仅存储一个 ID 和一个 stream_id。
所以至少你可能有一些看起来像
create table photos(id integer primary key, stream_id integer references streams(id) not null);
但您可能还需要描述和其他独立于存储的信息。
流表将包含有关流的所有通用信息,但将具有polymorphic association 到依赖于流类型的类。因此,您可以根据使用的实际流使用该关联来获取 S3Stream 或 DropBoxStream 的实例。
该实例(也是一个 ActiveRecord 资源)可以存储访问密钥,以及诸如保管箱、文件夹路径等内容。此外,该实例可以提供方法来构造给定 Photo 对象的 URI。
如果特定技术需要缓存已签名的 URI,则假设 S3Stream 对象可以引用已签名 URI 的 S3SignedUrl 模型。
如果证明 DropBox 和 S3 之间的签名 URL 代码相似,那么您可能只有一个 SignedUrl 模型。
当您设计 ios 和 android 客户端时,关键是不能让它们访问流所有者的访问令牌。相反,您需要在服务器应用程序中进行所有签名。您不希望设备的妥协导致暴露访问令牌造成计费问题以及隐私暴露。
希望这会有所帮助。