Amazon S3のAWS署名バーション2の廃止

S3の署名バージョン2が廃止になる。

– 以前の AWS リージョンの一部では、Amazon S3 で署名バージョン 4 と署名バージョン 2 がサポート。ただし、署名バージョン 2 は廃止され、署名バージョン 2 の最終サポートは 2019 年 6 月 24 日に終了
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/UsingAWSSDK.html#UsingAWSSDK-sig2-deprecation

2016年5月以前にリリースされた AWS SDK を使用する場合、次の表に示すように、署名バージョン 4 のリクエストが必要になることがある
AWS CLI

$ aws configure set default.s3.signature_version s3v4
$ aws configure set profile.your_profile_name.s3.signature_version s3v4

Java SDK

System.setProperty(SDKGlobalConfiguration.ENABLE_S3_SIGV4_SYSTEM_PROPERTY, "true");
-Dcom.amazonaws.services.s3.enableV4

JavaScript SDK

var s3 = new AWS.S3({signatureVersion: 'v4'});

PHP SDK

									
$s3 = new S3Client(['signature' => 'v4']);

Python-Boto SDK

[s3] use-sigv4 = True

Ruby SDK

s3 = AWS::S3::Client.new(:s3_signature_version => :v4)
s3 = Aws::S3::Client.new(signature_version: 'v4')

.NET SDK

AWSConfigsS3.UseSignatureVersion4 = true;

つまり、AWS SDKを使っている場合は、バージョンを確認
– AWS SDK for Java v1 →Java 1.11.x あるいは v2 in Q4 2018 にアップグレード。
– AWS SDK for Java v2 ※アップグレード不要
– AWS SDK for .NET v1 →3.1.10 以降にアップグレード
– AWS SDK for .NET v2 →3.1.10 以降にアップグレード
– AWS SDK for .NET v3 ※アップグレード不要
– AWS SDK for JavaScript v1 →主要バージョン V3 in Q3 2019 にアップグレード
– AWS SDK for JavaScript v2 →2.68.0 以降にアップグレード
– AWS SDK for JavaScript v3 →主要バージョン V3 in Q3 2019 にアップグレード
– AWS SDK for PHP v1 →主要バージョン V3 にアップグレード
– AWS SDK for PHP v2 →主要バージョン V3 にアップグレード
– AWS SDK for PHP v3 ※アップグレード不要
– Boto2 →Boto2 v2.49.0 にアップグレード
– Boto3 →1.5.71 (Botocore)、1.4.6 (Boto3) にアップグレード
– AWS CLI →1.11.108 にアップグレード
– AWS CLI v2 ※アップグレード不要
– AWS SDK for Ruby v1 →Ruby V3 にアップグレード
– AWS SDK for Ruby v2 →Ruby V3 にアップグレード
– AWS SDK for Ruby v3 ※アップグレード不要
– Go ※アップグレード不要
– C++ ※アップグレード不要

Upload the image from the php form to s3

It is necessary to make access right to s3 bucket beforehand with IAM.
Use php library to upload to s3. Here is code.

require 'vendor/autoload.php';

if(file_exists($_FILES['upfile']['tmp_name'])){
	$ext = substr($_FILES['upfile']['name'], strrpos($_FILES['upfile']['name'],'.') + 1);
	echo $ext."<br>";
	if(strtolower($ext) !== 'png' && strtolower($ext) !== 'jpg' && strtolower($ext) !== 'jpeg' && strtolower($ext) !== 'gif'){
		echo '画像以外のファイルが指定されています。画像ファイル(png/jpg/jpeg/gif)を指定して下さい';
		exit();
	}

	$tmpname = str_replace('/tmp/', '', $_FILES['upfile']['tmp_name']);
	echo $tmpname;
	$s3client = new Aws\S3\S3Client([
			'credentials' => [
					'key' => '',
					'secret' => ''
			],
			'region' => 'ap-northeast-1',
			'version' => 'latest',
	]);

	$result = $s3client->putObject([
			'Bucket' => 'zeus-image',
			'Key' => 'test.png',
			'SourceFile' => $_FILES['upfile']['tmp_name'],
			'Content-Type' => mime_content_type($_FILES['upfile']['tmp_name']),
	]);

}


?>
<div id="content">
<h2>画像管理</h2>
<hr>
<form action="#" method="POST" enctype="multipart/form-data">
<div id="drag-drop-area">
 <div class="drag-drop-inside">
  <p class="drag-drop-info">ここにファイルをアップロード</p>
  <p>または</p>
  <!-- <input type="file" value="ファイルを選択" name="image"> -->
  <p class="drag-drop-buttons"><input id="fileInput" type="file" value="ファイルを選択" name="upfile"></p>
      <input type="submit" value="送信">
   </div>
  </div>
</form>

HTML form view

s3

You can confirm that it is being uploaded properly.

S3にアップロードしてmysqlに登録:S3 / IAM編

まず、awsコンソールにログインし、S3でバケットを作成します。適当に[zeus-image]としておきましょう。リージョンはアジアパシフィック東京でいいでしょう。

続いてプロパティ
バージョニング、アクセスログの記録、タグ、オブジェクトレベルのログ記録、デフォルト暗号化、cloudWatchリクエストメトリクス、いずれも特に設定はしません。

続いてアクセス権
デフォルトではチェックボックスに全てチェックが入っています。


このバケットのパブリックアクセスコントロールリスト (ACL) を管理する
– 新規のパブリック ACL と、パブリックオブジェクトのアップロードをブロックする (推奨)
– パブリック ACL を通じて付与されたパブリックアクセスを削除する (推奨)

このバケットのパブリックバケットポリシーを管理する
– 新規のパブリックバケットポリシーをブロックする (推奨)
– バケットにパブリックポリシーがある場合、パブリックアクセスとクロスアカウントアクセスをブロックする (推奨)


このまま作成します。

IAMでユーザ追加
ユーザを追加していきます。

アクセスの種類で「プログラムによるアクセス」にチェックを入れます。

アクセスキー IDとシークレットアクセスキーを保存します。

続いて、対象ユーザからインラインポリシーの追加を押下します。

s3の指定bucketへのアクセス付与をします。

うおー、なんかやる気がでねーぞ。
続いてcomposerを入れていきます。

[vagrant@localhost app]$ curl -sS https://getcomposer.org/installer | php
All settings correct for using Composer
Downloading…

Composer (version 1.8.0) successfully installed to: /home/vagrant/local/app/composer.phar
Use it: php composer.phar

[vagrant@localhost app]$ php composer.phar install aws/aws-sdk-php
Invalid argument aws/aws-sdk-php. Use “composer require aws/aws-sdk-php” instead to add packages to your composer.json.

あれ??

S3にアップロードしてmysqlに登録

やりたいこと
– Laravelから画像をS3にアップロードしてmysqlにパスを登録

-> その為には?
– ブレークダウンして考える
– まず、s3に画像をアップロード
– その後、ユーザID、s3のバケットのパス、ファイル名、ファイルサイズ、ステータスをmysqlに登録する
– ユーザIDに紐づいた画像を画像管理の画面で表示させる

アップロードのHTML、JSまではできている。

<form action="#" method="POST" enctype="multipart/form-data">
        <div id="drag-drop-area">
         <div class="drag-drop-inside">
          <p class="drag-drop-info">ここにファイルをアップロード</p>
          <p>または</p>
          <!-- <input type="file" value="ファイルを選択" name="image"> -->
          <p class="drag-drop-buttons"><input id="fileInput" type="file" value="ファイルを選択" name="image"></p>
              <!-- <input type="submit" value="送信"> -->
           </div>
          </div>
            

      <div class="button_wrapper remodal-bg">
         <button type="submit" value="送信" id="square_btn" onClick="location.href='#modal'">登録</button>
      </div>
       </form> 

ログイン機能は後から作ろうかなと悠著に考えていたが、先に作った方が良いのかな。。
まずは、S3へのアップロードからやりましょう。

IAMロールを作成する

IAMロールを作成する
ポリシーには以下二つの権限をつける。
-AWSLambdaBasicExecutionRole
-AmazonS3FullAccess

'use strict';

const aws = require('aws-sdk');
const s3 = new aws.S3();

exports.handler = function(event, context){
	console.log('Received event:', JSON.stringify(event, null, 2));

	const uploadBucket = event.Records[0].s3.bucket.name;
	const key = event.Records[0].s3.object.key;

	const params = {
		Bucket: uploadBucket,
		Key: key
	};
	s3.getObject(params, function(err, data){
		if(err){
			console.log(err, err.stack);
			context.done(err, err.stack);
		} else {
			console.log('data: ', data);

			const copyBucket = 'sample-copy-bucket';
			const params = {
				Bucket: copyBucket,
				Key: key,
				Body: data.Body
			};
			s3.putObject(params, function(err, data){
				if(err){
					console.log(err, err.stack);
					context.done(err, err.stack);
				} else {
					console.log('data: ', data);
					context.suceed('complete!');
				}
			});
		}
	});
};

amazon lambdaとは?

amazon lambdaとは?
– 事前に定義したコードを実行するサービス
– 処理のトリガは何かしらのイベント(s3にファイル配置、ストリームデータ受信など)
– node.js//javaで実装
– サーバ、ロギング、スケーリングなどインフラ設計・管理が不要
– 実行回数によって課金

aws cloudTrail -> Source Bucket -> Amazon S3 -> AWS Lambda -> Lambda Function -> Access Policy -> Topic -> Amazon SNS

s3でbucketを作成します。

iamからロールを作成します。

s3を画像のcdnとして使おう

まずs3のバケットに画像をuploadして、パブリックのアクセス権を付与します。

できました。

取得した画像を別のドメインから接続します。

<img src="https://s3-ap-northeast-1.amazonaws.com/capital-technology/20181010114846.gif">

OK!

AWSには、ElastiCacheがあるようですね。
elastiCacheとは?
>ElastiCache は、クラウド内の分散型インメモリデータストア環境またはインメモリキャッシュ環境のセットアップ、管理、およびスケーリングが簡単になるウェブサービス
redisみたいなものか?

cloudfront

cloud front
-> 負荷を分散させ、大量のリクエストに対する対策を実施、通信にかかるレイテンシ(遅延)を改善

Amazon CloudFrontは、Amazon Web Services(AWS)のCDN(コンテンツデリバリネットワーク)サービス
– コンテンツファイルをサーバーから直接配信せず、CDNを介してユーザーに配信
– コンテンツをCloudFrontから配信すると、サーバーへのアクセスを減らせます。動的コンテンツをキャッシュすれば、データベースの負荷軽減も可能
– コンテンツがキャッシュされている限り、ユーザーは安定したレスポンスを得られる

localのcsvをmysqlにインポートする

1. まずdatabaseをつくります。
mysql> CREATE DATABASE click;
Query OK, 1 row affected (0.00 sec)

mysql> use click;

2. 続いて、tableを作ります。
mysql> create table articles(
-> id int primary key auto_increment,
-> login_id varchar(30),
-> role varchar(50),
-> name varchar(20),
-> password varchar(30),
-> mail varchar(255),
-> test_mail varchar(255),
-> updated_person varchar(50),
-> created_at datetime,
-> updated_at datetime
-> );

mysql> select * from articles;
Empty set (0.00 sec)

s3から取得したcsvをopenして1行目のカラムを飛ばしてmysqlにinsertしていきます。

try {
	$dbh = new PDO('mysql:host=localhost;dbname=click;charset=utf8','hoge','hogehoge', array(PDO::ATTR_EMULATE_PREPARES => false));
} catch(PDOException $e){
	exit('データベース接続失敗。'.$e->getMessage());
}

$stmt = $dbh->prepare('INSERT INTO articles VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?,?)');

$dbh->beginTransaction();
$fp = fopen('article.csv', 'rb');
$i = 0;
while ($row = fgetcsv($fp)){
	if($i == 0){
		$i++;
		continue;
	}
	if ($row === array(null)){
		continue;
	}
	$executed = $stmt->execute($row);
	$i++;
}
fclose($fp);
$dbh->commit();

確認してみましょう。

mysql> select * from articles;
+—-+———-+——–+————–+———–+———————+————————–+—————-+———————+———————+
| id | login_id | role | name | password | mail | test_mail | updated_person | created_at | updated_at |
+—-+———-+——–+————–+———–+———————+————————–+—————-+———————+———————+
| 1 | user1 | master | taniguchi | passowrd | laravel@gmail.com | laravel_test@gmail.com | sasaki | 2018-09-21 21:39:07 | 2018-09-21 21:39:07 |
| 2 | user2 | master | goto | himitsu | laravel@hotmail.com | laravel_test@hotmail.com | sasaki | 2018-09-22 08:31:54 | 2018-09-22 08:51:32 |
| 3 | user3 | master | 橋本芳樹 | password3 | laravel@gmail.com | laravel_test@gmail.com | こばやし | 2018-09-22 15:03:11 | 2018-09-22 15:03:11 |
| 4 | user4 | master | 後藤大輔 | password4 | laravel@gmail.com | laravel_test@gmail.com | こばやし | 2018-09-22 15:48:56 | 2018-09-22 15:48:56 |
| 9 | user2 | master | goto | himitsu | laravel@hotmail.com | laravel_test@hotmail.com | sasaki | 2018-09-22 17:41:59 | 2018-09-22 17:41:59 |
+—-+———-+——–+————–+———–+———————+————————–+—————-+———————+———————+
5 rows in set (0.00 sec)

おいおいおい、やべーことになってる。
とりあえず、laravel -> mysql(1) -> csv -> s3 upload -> s3 import -> csv -> mysql(2)の流れは出来た。やはり、laravelが時間かかったな。frameworkの習得は時間がかかる。s3はセキュリティ周りをもっと学習する必要がある。
next
-> SSL
-> githubからdeploy

csvをs3にアップロードしよう

composerを入れます。
[vagrant@localhost s3]$ curl -sS https://getcomposer.org/installer | php

aws sdkをインストール
[vagrant@localhost s3]$ php composer.phar require aws/aws-sdk-php

consoleでs3のバケットを作成する。

upload

require_once('vendor/autoload.php');

$s3client = new Aws\S3\S3Client([
	'credentials' => [
		'key' => 'A',
		'secret' => ''
	],
	'region' => 'ap-northeast-1',
	'version' => 'latest',
]);

$result = $s3client->putObject([
	'Bucket' => '',
	'Key' => 'article.csv',
	'SourceFile' => 'article.csv',
	'ContentType' => mime_content_type('article.csv'),
]);

おいおいおい、まじかー

まじかー。2回言ってしまった。

次はuploadしたS3のバケットからCSVをダウンロードして、mysqlの異なるdb・tableにinsertする。