Last active
December 17, 2015 18:40
-
-
Save yuku/5655239 to your computer and use it in GitHub Desktop.
Qiitaの画像アップロード機能も簡単に実装できる。そう、S3ならね。 ref: http://qiita.com/yuku_t/items/40b7daf018d3dab48974
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
S3_BUCKET = 'xxx' | |
AWS_SECRET_KEY = 'xxx' | |
AWS_ACCESS_KEY_ID = 'xxx' | |
# アクセスしてきたクライアントにS3へアップロードするためのpolicyと | |
# それをハッシュ化したsignatureを返す。 | |
def policies | |
# 0. セッションの確認など | |
# 1. 画像情報をバリデーションする | |
# ファイルサイズは大き過ぎないか、種類は適切か、など。 | |
# 2. policyを作る | |
# policyで許可した内容しかクライアントはアップロードできなくなる。 | |
key = '/path/to/file' # アップロード先のパス | |
policy_document = { | |
expiration: (Time.now + 1.minute).utc, # このポリシーは1分間のみ有効 | |
conditions: [ | |
# アップロード先のS3バケットを指定する | |
{ bucket: S3_BUCKET }, | |
# ファイルのS3上でのパスを指定する。 | |
# ワイルドカードも指定できるが、完全一致させておく。 | |
{ key: key }, | |
# オプション。クライアントから送られてきたものそのままにする。 | |
{ 'Content-Type' => params[:content_type] }, | |
# オプション。アップロード可能なファイルのサイズを範囲で指定できる。 | |
# クライアントから送られてきたファイルサイズをそのまま指定することで | |
# 1バイトでも大きさの異なるファイルは拒否できる。 | |
['content-length-range', params[:size], params[:size]] | |
] | |
}.to_json | |
policy = Base64.encode64(policy_document).gsub("\n", '') | |
# 3. signatureを作る | |
# AWSのシークレットキーとpolicyからsignatureを作る。 | |
# signatureはシークレットキーを知っている人しか計算できないので | |
# クライアントがpolicyを改ざんしてもAmazon側がそれを検知できる。 | |
signature = Base64.encode64( | |
OpenSSL::HMAC.digest( | |
OpenSSL::Digest::Digest.new('sha1'), | |
AWS_SECRET_KEY, policy)).gsub("\n", '') | |
# 4. アップロードに必要な情報をクライアントに返す | |
return { | |
url: "https://#{S3_BUCKET}.s3.amazonaws.com/", | |
form: { | |
'AWSAccessKeyId' => AWS_ACCESS_KEY_ID, | |
signature: signature, | |
policy: policy, | |
key: key | |
} | |
} | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var fileInput = $('input[type="file"]'); | |
fileInput.on('change', function (e) { | |
var file = e.target.files[0]; | |
// 0. 事前にファイルの大きさや種類をチェックする | |
// 1. サーバからpolicyとsignatureをもらう | |
// 上図でいう(1)に対応 | |
$.ajax({ | |
url: '/policies', | |
type: 'POST' | |
dataType: 'json' | |
data: { | |
// サーバにこれからアップロードするファイルの情報を渡す。 | |
size: file.size, // ファイルの大きさ | |
content_type: file.type // ファイルの形式 | |
} | |
}).done(function (data) { | |
// 2. サーバが返した情報をそのまま使ってFormDataを作る | |
var name, fd = new FormData(); | |
for (name in data.form) if (data.form.hasOwnProperty(name) { | |
fd.append(name, data.form[name]); | |
} | |
fd.append('file', file); // ファイルも忘れずに添付する | |
// 送信 | |
// 上図でいう(3)に対応 | |
var xhr = new XMLHttpRequest(); | |
xhr.open('POST', data.url, true) | |
xhr.send(fd); | |
}) | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var fileInput = $('input[type="file"]'); | |
fileInput.on('change', function (e) { | |
var file = e.target.files[0]; | |
// 0. 事前にファイルの大きさや種類をチェックする | |
// 1. サーバからpolicyとsignatureをもらう | |
// 上図でいう(1)に対応 | |
$.ajax({ | |
url: '/policies', | |
type: 'POST' | |
dataType: 'json' | |
data: { | |
// サーバにこれからアップロードするファイルの情報を渡す。 | |
size: file.size, // ファイルの大きさ | |
content_type: file.type // ファイルの形式 | |
} | |
}).done(function (data) { | |
// 2. サーバが返した情報をそのまま使ってFormDataを作る | |
var name, fd = new FormData(); | |
for (name in data.form) if (data.form.hasOwnProperty(name)) { | |
fd.append(name, data.form[name]); | |
} | |
fd.append('file', file); // ファイルも忘れずに添付する | |
// 送信 | |
// 上図でいう(3)に対応 | |
var xhr = new XMLHttpRequest(); | |
xhr.open('POST', data.url, true) | |
xhr.send(fd); | |
}) | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment