このライブラリを使うのが良い、とか、無駄にレイヤー重ねる記事が多くて辟易したので、シンプルなのを提示しておきます。
ファイルの分離の仕方はRailsっぽく書いてますが、Railsには依存しない話です。
(ちなみに、fogを使っても出来そうですが、fogを使うまでもなさそうです。)
認証済みURLを作る
Gemfile.rb
gem 'aws-sdk'
# Railsならinitializerとかその辺で
Aws.config.update({
region: 'ap-northeast-1',
credentials: Aws::Credentials.new(ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'])
})
S3_BUCKET = Aws::S3::Resource.new.bucket(ENV['AWS_S3_BUCKET'])
# あなたが神経質なら定数に入れずにシングルトンクラス作っても良いです
hoge.rake
# 先頭にスラッシュはつけない方がS3上のパスは綺麗になる
path = 'where/you/want/to/locate/file.png'
signed_url = S3_BUCKET.object(path).presigned_url(:put, expires_in: 36000)
puts signed_url
curlで送る
# signed_urlの所に上のrubyで作ったURLを貼る
# カレントディレクトリに debug.png というファイルがある想定
curl -X PUT --data-binary '@debug.png' signed_url
というわけで、curlコマンドでHTTPリクエストの形が明瞭になったので、あとはブラウザのJSなりiOS/Androidのコードなり、どこからでもアップロードできますね。めでたしめでたし。
蛇足: なんでputなのか?
REST的に、POSTは冪当性のない操作、PUTは冪当性のある操作に使うべきだからです。