6
11

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.

Cognito のIDプールでS3のユーザー毎フォルダにアクセスしてみる

Last updated at Posted at 2019-12-15

背景

AWS使ってサーバーレスで自分用の家計簿的なwebサービスを勉強も兼ねて開発中。
2つ前の記事
1つ前の記事
せっかくCognito使ったので、ユーザー毎のS3フォルダにアクセスする事をしてみたい。

構成

フロント:Vue.js + Element.ui
サーバーサイド:CloudFront + S3 + APIGateway + Lambda + DynamoDB + Cognito

やってみた

今回、様々なページを参考にさせてもらい、その情報を組み合わせました。もはやどの部分がどのページの参考なのかこんがらがっています。結構トライ&エラー発生し、各種設定行ったり戻ったりしました。今回は結果のみ共有させてもらいます。

まず、ブラウザからS3にアクセスする為、CORSの設定をします。

S3バケットのアクセス権限=>CORSの設定
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
    <AllowedHeader>Content-*</AllowedHeader>
    <AllowedHeader>Host</AllowedHeader>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

ログインユーザー毎にS3へのアクセスを許可する為、CognitoIDプール、認証済みユーザー用のIAMポリシーに以下設定。※以下の指定でhogehoge-bucketと指定していますが既に存在するようです。が、そのバケットを意味してないです。実際には自分作成のバケット名です。

認証済みユーザー用のIAMポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "cognito-identity:*",
                "mobileanalytics:PutEvents",
                "cognito-sync:*"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:DeleteObject",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::hogehoge-bucket/cognito/myhome-account/${cognito-identity.amazonaws.com:sub}",
                "arn:aws:s3:::hogehoge-bucket/cognito/myhome-account/${cognito-identity.amazonaws.com:sub}/*"
            ]
        }
    ]
}

そして処理本体、VueファイルのjavaScript部分。※ログイン処理が済んでいる事が前提です。ログイン部分は2つ前の記事を参照してみて下さい。

テスト本体
import AWS from 'aws-sdk'
import awsconfig from '../cognito/config'
import cognito from '@/cognito'

const S3_USERBACKETNAME = 'hogehoge-bucket'
const PROVIDER_KEY = 'cognito-idp.' + awsconfig.Region + '.amazonaws.com/' + awsconfig.UserPoolId

/* ・・中略・・ */

    s3test: function () {
      const cognitoUser = this.$cognito.userPool.getCurrentUser()
      cognitoUser.getSession((err, session) => {
        if (!err && session.isValid()) {
          const itoken = session.getIdToken().getJwtToken()

          // Initialize the Amazon Cognito credentials provider
          AWS.config.region = awsconfig.Region
          AWS.config.credentials = new AWS.CognitoIdentityCredentials({
            IdentityPoolId: awsconfig.IdentityPoolId,
            Logins: {
              [PROVIDER_KEY]: itoken
            }
          })
          var identityId = AWS.config.credentials.identityId
          var s3key = 'cognito/myhome-account/' + identityId + '/testfile.txt'

          // refresh AWS credentials
          AWS.config.credentials.refresh((err) => {
            if (err) {
              console.log(err)
            } else {
              var s3 = new AWS.S3({
                params: { Bucket: S3_USERBACKETNAME }
              })

              const updateParams = {
                Key: s3key,
                Body: 'teststring',
                ContentType: 'application/text'
              }

              s3.upload(updateParams, function (err, data) {
                if (err) {
                  console.log('error : ', err)
                } else {
                  console.log('success : ' + S3_USERBACKETNAME + '/' + s3key)
                }
              })
            }
          })
        }
      })
    }

これでテスト用の適当な文字列のファイルをS3のユーザー毎フォルダにアップ出来ました。間違ったフォルダを指定した時は AccessDenied: Access Denied で失敗する事も確認できました。

特にはまったポイント

  • credentialを取得する時に、一時トークンを渡すが、認証プロバイダーとしてcognitoユーザープールを使う場合にどんなキー(上記ソースのPROVIDER_KEY部分)を指定するのか情報を見つけるのに非常に時間がかかった。参考
  • ポリシーで指定するcognito-identity.amazonaws.com:subが実際には何の値を示すのか見つけるのに非常に時間がかかった。参考

参考にさせてもらったページ

ブラウザから Amazon S3 への写真のアップロード
サインイン後に ID プールを使用して AWS サービスへアクセスする
[ Serverless ] Cognito、S3、Lambdaで認証機能付きのWebサイトを作ってみました
【Cognito】Amazon Cognito Identity SDK for JavaScriptで動くサンプルを作ってみた #2/2【JavaScript】
WebブラウザからAmazon S3に直接ファイルをアップロードする
AWS Cognitoを使ってサーバレスアプリケーションに認証をつける

6
11
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
6
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?