S3　署名付きURLでファイル共有しようと思ってつまづいた

こんにちは。パエリアです。

最近写真や動画を取る機会があって、友人にも共有したかったのですが、容量が多くてLINEでは送れないということがありました。
<font color="Blue">Google Drive</font>などのSaaSを使えば簡単に実現可能だと思いますが、せっかくならAWSを利用して共有する方法を考えようと思い、実施しました。

筆者は普段、AWSの監視、運用しかやっておらず、開発経験はあまりありません。
あまりS3に触る機会もないので、内容はレベルが低いですが、ご容赦ください。
また、筆者はSAPを取得しており、AWSの各種サービスの概要等は知っていますが、触ったことのあるサービスはEC2やRDSくらいなので、持っている知識をできるだけ使ってみようという趣旨のもとサービスを検討、利用しています。

## どうやってファイル共有を実現するか
まずはじめに、どのサービスを使ってファイル共有を実現するかですが、<font color="blue">保存先は**S3**</font>で決まりでしょう。
次にダウンロード（共有）方法ですが、そのままオブジェクトをパブリック公開するのはセキュリティ上、問題があると考えました。
会社の書類を公開するわけではないので、そんなに気にすることではないかもしれませんが、友人との写真や動画を垂れ流しにすることにも少し抵抗があります。
（SNSで公開するのとどう違うんだと言われればそこまでなんですが、、、）

##①AWS Cognito ?
まず考えてみたのがAWS Cognitoでの連携。
>(頭の中)
>セキュリティを考えたら、やっぱりユーザーの認証とかすればかなり安全なんじゃないか
>　→AWSで認証のサービスと言えばAWS Cognitoでしょ
>　　→LINEとかSNSで連携して実装できればなんかちょっとすごいものができそう

よし、これで進めてみよう！
・・・・・・・めちゃめちゃ大変だ。
調べてみると可能ではあるのですが、<font color="Red">かなり時間がかかりそう</font>でした。
一部参考にさせていただいた記事を載せさせていただきます。
https://qiita.com/Futo_Horio/items/97586a3c16d939a8ab5f

##②署名付きURL?
SAAの試験で何度も見た　S3 署名付きURL。
「<font color="Blue">S3 セキュリティ</font>」と検索すると結構これが引っかかります。
AWSの試験でもよく出るし、何かしらAWSがベストプラクティスとして紹介しているサービスですね。

存在は知っていたけど、結局URLを知っていれば見ることはできるし、時間制限も友人とファイル共有するのならめんどくさいなーと思っていました。
しかし、①の方法より簡単だし、調べてみるとURLの中身は

`https://awsexamplebucket.s3.amazonaws.com/test.txt?AWSAccessKeyId=EXAMPLEACCESSKEYXXXX&Signature=XXXXEXHCcBe%EXAMPLEKnz3r8O0AgEXAMPLEXXXX&Expires=155553XXXX`

のようにハッシュ値のようなものが入った長いURLになるので、悪意があっても簡単には特定できなそうだと感じました。（小並感）
とはいえ、URLが知られてしまえば誰でも見れてしまうので、使うときは時間制限を設けてで少しでもリスクを減らしましょう。

ということで、こちらの方法で進めていきます。
####では、実際に署名付きURLを作成していきましょう。
方法はいくつかあるようですが、簡単な方法を２つ紹介します。

###①マネージメントコンソールから作成
1. 署名付きURLで公開したいファイルを選択する
![スクリーンショット_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646906/ec1dcb15-95d5-a010-e3c7-ee50941b3b44.jpeg)

2. 「開ける」ボタンをクリックする
![スクリーンショット_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646906/6a43dcbd-fcc2-8247-ffd9-6a13a3941fe3.jpeg)

3. ファイルの中身が表示されるので、そのURLをコピーして共有したい人に送る。
![スクリーンショット03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646906/9261a682-94db-7e7e-7af4-5f022b852a48.jpeg)

この方法では<font color="Blue">300秒(5分)</font>の期限の署名付きURLが発行されるようです。
署名付きURLの正式な作成方法ではなさそうですが、制限時間が５分間で問題なければこの方法が一番簡単ではないでしょうか。

###②CLIで作成
CLI環境が整っていない人は少し手間がかかるかもしれませんが、CLIが使えるなら簡単です。

一応、CLIインストールの公式のドキュメントを貼っておきます。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-mac.html

下記コマンドを実行するだけです。

```署名付きURL作成
aws s3 presign s3://バケット名/オブジェクト名（S3 URL） --expires-in 60
```

--expires-in　のあとには秒単位で有効期限を入力します。

コマンドを実行したらURLが作成、表示されるのでそれをコピーして共有したい人に送りましょう。

しかし、私はここでエラーが起きました。

```エラー①
aws s3 presign s3://バケット名/AWS Certified Solutions Architect.pdf --expires-in 60
Unknown options: Certified,Solutions,Architect.pdf
```

むむ。ちゃんとS3　URLをコピーしたのに、、、
このときは「AWS Certified Solutions Architect.pdf」というオブジェクト名のURLを作成しようとしていました。
このオブジェクト名に「スペース」が入ってしまっていることによって、その部分が<font color="red">コマンドの引数</font>として扱われてしまっていることが原因のようでした。

```正解①
aws s3 presign 's3://バケット名/AWS Certified Solutions Architect.pdf' --expires-in 60
```

これで、コマンドの実行はうまくいきました。しかし、URLを見に行くと、、、

```エラー②
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>PermanentRedirect</Code>
<Message>The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.</Message>
<Endpoint>バケット名.s3-ap-northeast-1.amazonaws.com</Endpoint>
・
・
・
```

指定されたエンドポイントを使用してアドレス指定してください、、、？？？

これはCLIの設定の問題でした。
コマンド実行時CLIを実行する環境の「.aws/config」にあるリージョンの設定が「region = us-east-2」となっていることが原因でした。
ここを<font color="Blue">対象オブジェクトに合わせたリージョン</font>（今回は「ap-northeast-1」）に修正し、コマンドを再実行することでエラーは解消されました。

リージョン指定の部分はなにか違う方法でも解決できそうですが、今回はここまでとします。

##まとめ
・ファイル共有は S3 の <font color="Blue">署名付きURL</font>を使ってみよう
・CLI コマンド実行時に　S3 URL　は <font color="red">**' '**</font> でくくっておこう。
・CLI コマンド実行時はエンドポイントに合わせた<font color="Blue">リージョン</font>を指定しよう。

今回私が出会ったエラーは、頻度は多くないエラーな気がしますが、少しでも同じような方のお力になれれば幸いです。

また、料金も気になる人もいると思いますので、公式のリンクを貼っておきます。
https://aws.amazon.com/jp/s3/pricing/

それでは、また次回。