17
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AmplifyのStorageと認証まわり

Last updated at Posted at 2020-01-26

AmplifyのStorageと認証まわり

はじめに

サーバーレスWebアプリ開発を進めてくなかで、AmplifyのStorageと認証まわりの理解が進んできて、完全に理解したなと思ってJAWS-UG浜松で発表しようとしたら全然できませんでした。
できなかったというか、話し始めようとしたら話せるほど自分のなかで整理できてないことに気付いてギブアップしました。発表内容はこれだけじゃなかったとはいえ、まぁ失礼な話ですよね。本当すみません。
リベンジすべく、整理するために記事を書きます。

Guest許可と認証ユーザーのみ

AmplifyのStorageをセットアップする際の質問のなかに以下のような質問があって、選択できます。

? Who should have access: (Use arrow keys)
  Auth users only 
  Auth and guest users 
  • Auth user only
    Storageへアクセスするためにユーザー認証(ログイン)が必要。
  • Auth and guest users
    ユーザー認証していない状態でもStorageへアクセスできる。

ファイルアップロード(put)

Amplifyを利用してファイルをS3にアップロードするJavaScriptのコード例

.js
  :
import { Storage } from 'aws-amplify';
  :
      Storage.put(filePath, image).then(result => {
        console.log(result);
      }).catch(err => console.log(err));

例えばfilePath = "a/b/c/test.jpg"とした場合、
resultには key : a/b/c/test.jpg のような結果(要はS3 Object key)が返ってきます。
そしてバケットには以下のようにpublic/a/b/c/test.jpgとしてファイルがアップロードされます。
Screenshot 2020-01-25 at 22.22.43.png
publicが先頭についてますが、これはアクセスレベルです。

AmplifyのStorageには3つのアクセスレベルがあります。

  • public : 全員が読み書きできる。
  • protected : 全員が読めるが、書けるのは自分だけ。
  • private : 自分しか読み書きできない。

protectedの場合は以下のように書きます。

.js
      Storage.put(filePath, image, {
          level: 'protected'
      }).then(result => {
        console.log(result);
      }).catch(err => console.log(err));

privateの場合は、protectedをprivateにすればいいだけです。

protectedやprivateの場合、アップロードされるパスの先頭には、アクセスレベルに続きCognito Identity IDが付きます。
ink (7).png

なお、Guestでprotectedやprivate指定した場合、以下の例外とともに HTTP403(Forbidden(閲覧禁止))が返ってきました。
AWSS3Provider - error uploading AccessDenied: Access Denied

ファイルダウンロード(アドレス取得)(get)

Amplifyを利用してS3にあるファイルの参照URLを取得するJavaScriptのコード例

      Storage.get(s3key).then(result => {
        this.imageURL = result;
      }).catch(err => console.log(err));

s3key = "a/b/c/test.jpg"このように、s3keyにはアクセスレベル名やCognito Identity IDを付けないことに注意。

resultに以下のようなURLが取得できます。
https://sample-vue-project-bucket-work.s3.ap-northeast-1.amazonaws.com/public/a/b/c/test.jpg?X-Amz-Algorithm=xxx&X-Amz-Credential=xxx&X-Amz-Date=xxx&X-Amz-Expires=900&X-Amz-Security-Token=xxx&X-Amz-Signature=xxx&X-Amz-SignedHeaders=host
後ろに認証のための色々なパラメータが付いてますね。これがないとアクセスが拒否されます。
また、デフォルトで900秒(15分)という有効期限も付いています。

任意の有効期限を指定することもできます。

      let s3key = "a/b/c/test.jpg"
      let dataExpireSeconds = (30 * 60);
      Storage.get(s3key, { expires: dataExpireSeconds }).then(result => {
        this.imageURL = result;
      }).catch(err => console.log(err));

適切な認証パラメータではなかったり、有効期限が切れた後にgetすると、HTTP403(Forbidden(閲覧禁止))とともにエラーが返ってきます。

<Error>
  <Code>AccessDenied</Code>
  <Message>Access Denied</Message>
  <RequestId>D43YC2E5080A822C</RequestId>
  <HostId>
    w7zzd5NRpm8Ih0DN3hmjZT8sDQT5hcV7FhqbUaW6ZG7SpsepV3UspzDUMDVKRkPesaUpyUSEGC0=
  </HostId>
</Error>

<Error>
  <Code>AccessDenied</Code>
  <Message>Request has expired</Message>
  <X-Amz-Expires>900</X-Amz-Expires>
  <Expires>2020-01-26T03:07:16Z</Expires>
  <ServerTime>2020-01-26T03:20:13Z</ServerTime>
  <RequestId>9F14A2CA61AE75F2</RequestId>
  <HostId>
    wru7usdhgiI2MXWsdFGh59x8JYl1TbOzPDMs2L5LZ/IwDD9tueInxK7bfh/rKftjJZCCf9CY7SE=
  </HostId>
</Error>

AmplifyのAuthによる認証

ゲストを許可した場合は不要ですが、そうではない場合は認証をパスした状態でputやgetをする必要があります。

ユーザーにサインインしてもらう

Amplifyを利用した一般的な実現方法としては、AmplifyのAuthの基本機能を利用して、ユーザーにアカウントを作ってもらったうえでサインインしてもらう形になるかと思います。
Screenshot 2020-01-26 at 13.15.46.png
こんな感じの画面でユーザー登録や認証の基盤を構築することがサクッと実現できちゃいます。
AmplifyでAuthをセットアップをする手順などの詳細は、この記事では割愛します。

プログラムで自動的に認証する

ユーザーがログインしなくてもサービスを利用できるようにしたい場合、一般的にはゲストを許可する設定でセットアップして、ゲストとして処理してあげればいいと思います。
ただ、あえてゲストは利用せず、サービス側が予め用意したアカウントで自動的(ユーザーに意識させず)に認証をパスするということもできます。
細かな手順などはこちらの記事に書いてありますので、やはりこの記事では割愛します。
Cognitoユーザーを作成したうえで、JavaScriptで自動的にログインをします。

あとがき

まずは何か動くものを作る。座学よりも効率的に学ぶことができると思っています。
それを人に説明しようとした場合、やはりある程度は整理してまとめるという作業が必要になってきますね。改めて実感しました。
これからはちゃんと準備してから話をしようと思います。

さて今回はStorage観点での認証の話でしたが、次は認証そのもの、その中でも特にソーシャルログインについて学びたいと考えています。
アカウント作成って心理的ハードルが高く、また、手間がかかると思っていて、とはいえユーザー毎の情報を保護することも必要だと思ってます。
多少でも心理的ハードルを下げ、また、ユーザー認証の手間を少なくしてくれるソーシャルログインは、サービスにとって必須の機能ではないでしょうか。と、思うわけなんです。

17
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?