HTML アップロードフォームから S3 へのファイルアップロード
S3 というのは Amazon の Simple Storage Service で、スケーラブルなクラウドストレージサービスです。
ここでは HTML のフォームから S3 へファイルをアップロードする方法を示します。
ポイントになるのは、アクセスキーの設定およびポリシーの設定などになります。
HTML フォームから S3 へのファイルアップロード
HTML のファイルアップロードフォームはこのような形になります。
<form action="http://XXXXX.s3.amazonaws.com/"
method="post"
enctype="multipart/form-data">
<input type="hidden" name="key" value="uploads/myfilename.jpg">
<input type="hidden" name="AWSAccessKeyId"
value="あなたの AWS アクセスキー">
<input type="hidden" name="acl" value="public-read">
<input type="hidden" name="success_action_redirect"
value="http://example.com/upload_ok.html">
<input type="hidden" name="policy"
value="ポリシーファイルの Base 64 (後述)">
<input type="hidden" name="signature" value="シグネチャ">
<input type="hidden" name="Content-Type" value="image/jpeg">
<input name="file" type="file">
<input type="submit" value="S3 へのアップロード">
</form>
形式は普通に一般的なものです (詳細は「HTML フォーム・ファイルアップロードの仕組み」を参考にしてください。)
よくみると、hidden の input として、key、AWSAccessKeyId、acl、success_action_redirect、policy、signature、Content-Type などの値が設定されています。
key というのは、アップロード先の S3 ストレージでのファイル名にあたるものです。ここでは、uploads/myfilename.jpg としていますが、これによって、 uploads というフォルダ内の myfilename.jpg というキー名でアップロードされたファイルが保存されることになります。
AWSAccessKeyId は AWS の管理画面でとれるあなたのアクセスキーを設定します。
acl はアップロード後のファイルのアクセス権を設定します。ここでは public-read にしていますから、 アップロード後、直ちに誰でもそのファイルが閲覧可能になります。設定しなければプライベートになります。
success_action_redirect はファイルアップロードが成功したあとに、リダイレクトされる先です。
policy と signature は後ほど説明します。
Content-Type はアップロードするファイルの MIME タイプをセットします。
S3 へのアップロード時のポリシーとシグネチャ設定
さて、設定しなければならないパラメータとしてポリシーとシグネチャについて説明します。
ポリシーについては、例えば次のような形式で有効期限、バケツ、キー名のルール (starts-with)、acl、success_action_redirect、 Content-Type のルールを設定します。
{ "expiration": "2020-01-01T12:00:00.000Z", "conditions": [ {"bucket": "mybucket"}, ["starts-with", "$key", "uploads/"], {"acl": "public-read"}, {"success_action_redirect": "http://example.com/upload-ok.html"}, ["starts-with", "$Content-Type", "image/"] ] }
ポリシーについては、これを Base64 エンコードして policy 値として設定します。
シグネチャについては、エンコードされたポリシーに対して AWS シークレットキーをパスワードとして、HMAC-SHA-1 を設定します。
参考までにこれを計算する Java プログラムは次のようになります。
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import sun.misc.BASE64Encoder;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class sigapp1 {
public static void main(String[] args) {
final String aws_secret_key = "あなたの AWS シークレットキー";
try {
String policy_document = getFileContents("policy.txt");
String policy = (
new BASE64Encoder()).encode(
policy_document.getBytes("UTF-8")).replaceAll(
"\n","").replaceAll(
"\r","");
System.out.println("Policy:");
System.out.println(policy);
System.out.println("");
Mac hmac;
hmac = Mac.getInstance("HmacSHA1");
hmac.init(new SecretKeySpec(aws_secret_key.getBytes(
"UTF-8"), "HmacSHA1"));
String signature = (new BASE64Encoder()).encode(hmac.doFinal(
policy.getBytes("UTF-8"))).replaceAll(
"\n", "");
System.out.println("Signature:");
System.out.println(signature);
System.out.println("");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
protected static String getFileContents(String path)
throws IOException {
StringBuffer sb = new StringBuffer();
BufferedReader buffReader = new BufferedReader(
new FileReader(path));
String line;
while( (line = buffReader.readLine()) != null ){
sb.append(line);
}
buffReader.close();
return sb.toString();
}
}
このプログラムで出力された値を policy および signature にセットすれば OK です。