aws-amplify-vueのサンプルアプリで画像アップロードを動かすためにやったこと

aws-amplify-vueのサンプルアプリで画像アップロードを試そうとしたところ、「Missing credentials in config」というエラーが発生し、画像アップロードが動きませんでした。 GitHubのissueを参考にソースを修正する事で解決したので、手順をご紹介します。
2018.11.13

はじめに

サーバーレス開発部@大阪の岩田です。 Aws AmplifyがVue.jsに対応した事もあり、最近Vue.jsをちょこちょこ触っています。

サンプルアプリをイジリながら、色々試していたところ下記のようにMissing credentials in configというエラーが出て画像アップロードの処理がうまく動きませんでした。

GitHubのissueを参考にソースを修正する事で解決したので、手順をご紹介します。

環境

Node.jsのバージョンはv8.10.0を使用しました。

ライブラリのバージョンは下記の通りです

npm list --depth=0
aws-amplify-vue-sample@1.0.0 /Users/...........aws-amplify-vue
├── autoprefixer@7.2.6
├── aws-amplify@1.1.4
├── aws-amplify-vue@0.1.1
├── aws-sdk@2.354.0
├── babel-core@6.26.3
├── babel-eslint@7.2.3
├── babel-helper-vue-jsx-merge-props@2.0.3
├── babel-loader@7.1.5
├── babel-plugin-syntax-jsx@6.18.0
├── babel-plugin-transform-runtime@6.23.0
├── babel-plugin-transform-vue-jsx@3.7.0
├── babel-preset-env@1.7.0
├── babel-preset-stage-2@6.24.1
├── chalk@2.4.1
├── copy-webpack-plugin@4.6.0
├── css-loader@0.28.11
├── e@0.0.4
├── eslint@3.19.0
├── eslint-friendly-formatter@3.0.0
├── eslint-loader@1.9.0
├── eslint-plugin-html@3.2.2
├── eventsource-polyfill@0.9.6
├── extract-text-webpack-plugin@3.0.2
├── file-loader@1.1.11
├── friendly-errors-webpack-plugin@1.7.0
├── fsts@0.0.39
├── html-webpack-plugin@2.30.1
├── node-notifier@5.3.0
├── optimize-css-assets-webpack-plugin@3.2.0
├── ora@1.4.0
├── portfinder@1.0.19
├── postcss-import@11.1.0
├── postcss-loader@2.1.6
├── rimraf@2.6.2
├── semver@5.6.0
├── shelljs@0.7.8
├── uglifyjs-webpack-plugin@1.3.0
├── url-loader@0.5.9
├── vue@2.5.17
├── vue-loader@13.7.3
├── vue-router@3.0.1
├── vue-style-loader@3.1.2
├── vue-template-compiler@2.5.17
├── vuex@3.0.1
├── webpack@3.12.0
├── webpack-bundle-analyzer@2.13.1
├── webpack-dev-server@2.11.3
└── webpack-merge@4.1.4

サンプルアプリを動かしてみる

実際にサンプルアプリを動かすまでの手順です。 サンプルアプリのREADMEに記載されている手順に従ってセットアップして行きます。

サンプルアプリの取得とライブラリの導入

git clone https://github.com/aws-samples/aws-amplify-vue.git
cd aws-amplify-vue-sample
npm install

AWSリソースの作成

amplifyコマンドで諸々のリソースを作成して行きます。amplifyコマンド未導入の場合は先に npm install -g aws-amplify/cli でamplifyコマンドをインストールしておいて下さい。

amplify init
amplify init

Note: It is recommended to run this command from the root of your app directory
? Choose your default editor:
  Sublime Text
  Visual Studio Code
  Atom Editor
  IDEA 14 CE
❯ Vim (via Terminal, Mac OS only)
  Emacs (via Terminal, Mac OS only)
  None

? Choose the type of app that you're building (Use arrow keys)
  android
  ios
❯ javascript

? What javascript framework are you using (Use arrow keys)
  react
  react-native
  angular
  ionic
❯ vue
  none

? Source Directory Path:  (src)
? Distribution Directory Path: (dist)
? Build Command:  (npm run-script build)
? Start Command: (npm run-script serve)

Using default provider awscloudformation

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html

? Do you want to use an AWS profile? (Y/n)

? Please choose the profile you want to use
  default
❯ amplify-cli-user

⠧ Initializing project in the cloud...

CREATE_IN_PROGRESS awsamplifyvue-20181113141235 AWS::CloudFormation::Stack Tue Nov 13 2018 14:12:36 GMT+0900 (JST) User Initiated
CREATE_IN_PROGRESS AuthRole                     AWS::IAM::Role             Tue Nov 13 2018 14:12:39 GMT+0900 (JST)
CREATE_IN_PROGRESS UnauthRole                   AWS::IAM::Role             Tue Nov 13 2018 14:12:40 GMT+0900 (JST)
CREATE_IN_PROGRESS DeploymentBucket             AWS::S3::Bucket            Tue Nov 13 2018 14:12:40 GMT+0900 (JST)
CREATE_IN_PROGRESS AuthRole                     AWS::IAM::Role             Tue Nov 13 2018 14:12:41 GMT+0900 (JST) Resource creation Initiated
CREATE_IN_PROGRESS UnauthRole                   AWS::IAM::Role             Tue Nov 13 2018 14:12:41 GMT+0900 (JST) Resource creation Initiated
CREATE_IN_PROGRESS DeploymentBucket             AWS::S3::Bucket            Tue Nov 13 2018 14:12:42 GMT+0900 (JST) Resource creation Initiated
✔ Successfully created initial AWS cloud resources for deployments.

Your project has been successfully initialized and connected to the cloud!

Some next steps:
"amplify status" will show you what you've added already and if it's locally configured or deployed
"amplify <category> add" will allow you to add features like user login or a backend API
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud

Pro tip:
Try "amplify add api" to create a backend API and then "amplify publish" to deploy everything



CREATE_COMPLETE AuthRole                     AWS::IAM::Role             Tue Nov 13 2018 14:12:58 GMT+0900 (JST)
CREATE_COMPLETE UnauthRole                   AWS::IAM::Role             Tue Nov 13 2018 14:12:59 GMT+0900 (JST)
CREATE_COMPLETE DeploymentBucket             AWS::S3::Bucket            Tue Nov 13 2018 14:13:03 GMT+0900 (JST)
CREATE_COMPLETE awsamplifyvue-20181113141235 AWS::CloudFormation::Stack Tue Nov 13 2018 14:13:05 GMT+0900 (JST)
amplify add auth
amplify add auth

Using service: Cognito, provided by: awscloudformation
 The current configured provider is Amazon Cognito.
 Do you want to use the default authentication and security configuration? Yes, use the default configuration.
Successfully added resource cognitoc9444f00 locally

Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
amplify add storage
amplify add storage

? Please select from one of the below mentioned services (Use arrow keys)
❯ Content (Images, audio, video, etc.)
  NoSQL Database

? Please provide a friendly name for your resource that will be used to label this category in the project: (s35c4b6179)

? Please provide bucket name: (awsamplifyvue54779a49be8043e088f681268e45d928)
          
? Who should have access: (Use arrow keys)
❯ Auth users only
  Auth and guest users
    
? What kind of access do you want for Authenticated users (Use arrow keys)
  read
  write
❯ read/write

Successfully added resource s35c4b6179 locally

Some next steps:
"amplify push" builds all of your local backend resources and provisions them in the cloud
"amplify publish" builds all of your local backend and front-end resources (if you added hosting category) and provisions them in the cloud
amplify add api
amplify add api

? Please select from one of the below mentioned services (Use arrow keys)
❯ GraphQL
  REST
  
? Provide API name: (awsamplifyvue)  

? Choose an authorization type for the API
  API key
❯ Amazon Cognito User Pool

? Do you have an annotated GraphQL schema? (y/N)

? Do you want a guided schema creation? (Y/n)

? What best describes your project: (Use arrow keys)
❯ Single object with fields (e.g., “Todo” with ID, name, description)
  One-to-many relationship (e.g., “Blogs” with “Posts” and “Comments”)
  Objects with fine-grained access control (e.g., a project management app with owner-based authorization)

? Do you want to edit the schema now? (Y/n)  

? Press enter to continue

GraphQL schema compiled successfully. Edit your schema at /Users/xxxxxxx/aws-amplify-vue/amplify/backend/api/awsamplifyvue/schema.graphql
Successfully added resource awsamplifyvue locally

Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
amplify push
amplify push

| Category | Resource name   | Operation | Provider plugin   |
| -------- | --------------- | --------- | ----------------- |
| Auth     | cognitoc9444f00 | Create    | awscloudformation |
| Storage  | s35c4b6179      | Create    | awscloudformation |
| Api      | awsamplifyvue   | Create    | awscloudformation |
? Are you sure you want to continue? (Y/n)

GraphQL schema compiled successfully. Edit your schema at /Users/xxxxxx/aws-amplify-vue/amplify/backend/api/awsamplifyvue/schema.graphql
? Do you want to generate code for your newly created GraphQL API (Y/n) 
? Choose the code generation language target (Use arrow keys)
❯ javascript
  typescript
  flow
? Enter the file name pattern of graphql queries, mutations and subscriptions (src/graphql/**/*.js)
? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions (Y/n)
? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions Yes

⠋ Updating resources in the cloud. This may take a few minutes...

UPDATE_IN_PROGRESS awsamplifyvue-20181113141235 AWS::CloudFormation::Stack Tue Nov 13 2018 14:20:42 GMT+0900 (JST) User Initiated
CREATE_IN_PROGRESS storages35c4b6179            AWS::CloudFormation::Stack Tue Nov 13 2018 14:20:46 GMT+0900 (JST)
CREATE_IN_PROGRESS authcognitoc9444f00          AWS::CloudFormation::Stack Tue Nov 13 2018 14:20:47 GMT+0900 (JST)
CREATE_IN_PROGRESS storages35c4b6179            AWS::CloudFormation::Stack Tue Nov 13 2018 14:20:48 GMT+0900 (JST) Resource creation Initiated
CREATE_IN_PROGRESS authcognitoc9444f00          AWS::CloudFormation::Stack Tue Nov 13 2018 14:20:49 GMT+0900 (JST) Resource creation Initiated
⠸ Updating resources in the cloud. This may take a few minutes...

CREATE_IN_PROGRESS awsamplifyvue-20181113141235-storages35c4b6179-1FPFQAI1UNGXH   AWS::CloudFormation::Stack Tue Nov 13 2018 14:20:48 GMT+0900 (JST) User Initiated
CREATE_IN_PROGRESS awsamplifyvue-20181113141235-authcognitoc9444f00-17PFDDOAXMSPT AWS::CloudFormation::Stack Tue Nov 13 2018 14:20:49 GMT+0900 (JST) User Initiated
CREATE_IN_PROGRESS S3Bucket                                                       AWS::S3::Bucket            Tue Nov 13 2018 14:20:52 GMT+0900 (JST)
⠹ Updating resources in the cloud. This may take a few minutes...    
...
...
...

amplify pushが完了したらCloudFormationのスタック更新が正常終了していることを確認します。

OKです。準備完了です。

サンプルアプリの実行

npm startでサンプルアプリを起動すると、、、

いつものAmplifyのサインイン画面が表示されるので、サインアップ後にプロフィールへ進みます。

ここで画像のアップロードを試みると、冒頭のエラーが発生しました。

ソースコードの修正

先ほどのエラーについて調べたところ、GitHubにissueが上がっていました。 サンプルアプリが使っているAws AmplifyのStorageコンポーネントがaws-sdkのs3クライアントにうまく認証情報を渡せていないようです。

main.jsにハイライト箇所を追加します。

main.js

/*
 * Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
 * the License. A copy of the License is located at
 *
 *     http://aws.amazon.com/apache2.0/
 *
 * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
 * and limitations under the License.
 */

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue';
import App from './App'
import router from './router';
import Amplify from 'aws-amplify';
import aws_exports from './aws-exports';
import { components } from 'aws-amplify-vue'; 

Vue.config.productionTip = false

Amplify.configure(aws_exports)

import Storage from '@aws-amplify/storage';
import S3 from 'aws-sdk/clients/s3';
const hackyCreateS3 = (options) => {
  const { bucket, region, credentials } = options;
  return new S3({
    apiVersion: '2006-03-01',
    params: { Bucket: bucket },
    region: region,
    credentials: credentials
  });
}
Storage._createS3 = hackyCreateS3;

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router: router,
  template: '<App/>',
  components: { 
    App,
    ...components
  }
})

再挑戦

改めてプロフィール画像をUPしてみます

今度はうまくいきました!!

まとめ

久しぶりにAWS Amplifyを触ったのですが、いつの間にかamplify/cliが使えるようになり、諸々のAWSリソース作成がとても簡単になっていました。 今回はVue.jsと関係ないところでハマってしまったのですが、今後Vue.jsの勉強も頑張っていこうと思います。 誰かの参考になれば幸いです。