AWS Amplify Framework(4)APIカテゴリ

APIカテゴリ

APIカテゴリは、 REST および、AWS Appsync をはじめとする GraphQL エンドポイントへのHTTPリクエストを行うための機能を、JavascriptライブラリおよびSDKを通じて提供する。AppSyncとの統合を行う場合は、

  1. クライアント側でAPIエンドポイントと認証情報を設定
  2. APIスキーマからJavascriptコードを生成
  3. クエリやミューテーションを実行するアプリコードを生成

という手順で行う。また、 Amplify CLI を用いることでバックエンドとなる AWS Appsync の設定やクライアント側の設定ファイルのダウンロードなどを簡単に行うことができる。

セットアップ

Amplifyプロジェクトのルートディレクトリでamplify add apiコマンドを実行することで、ウィザードに従って自動セットアップを行うことができる。

amplify update api
? Please select from one of the below mentioned services: GraphQL
? Choose the default authorization type for the API Amazon Cognito User Pool
Use a Cognito user pool configured as a part of this project.
? Do you want to configure advanced settings for the GraphQL API No, I am done.

スキーマ

/amplify/backend/api/API_NAME/schema.graphql にあるスキーマファイル(schema.graphql)を編集することで、GraphQLのスキーマを更新することができる。Amplifyプロジェクトをデプロイすると、これらのスキーマがバックエンド側に反映される。

GraphQLトランスフォーマ

Amplifyには、拡張定義された GraphQLディレクティブ が用意されており、これらのディレクティブを用いることで、 データ構造や参照権限などを簡単に記述 することができる。

type User @model @key(fields: ["id", "group"]) {
  id: ID!
  group: String!
  attr: Attr
}

type Attr {
  gender: Int
  age: Int
  areacode: Int
  postcode: Int
}
ディレクティブ 内容
@model @model単位でDynamoDBテーブルが作成される
@key(fields: [KEY, KEY]) DynamoDBに格納する際のプライマリキーとソートキーを定義

スキーマの更新

フロントエンドのコンテンツは、GraphQLデータを操作するためのTypeScriptクラスを経由して、バックエンドと通信を行う。amplify codegen を実行することで、 /arc/graphql/ 以下にGraphQLを操作するためのGraphQLステートメントとタイプを自動生成する。

なお、amplify codegen コマンドは、 team-provider-info.json に格納されている情報を基にAWS上の設定内容を確認し、上記動作を行う。したがって、 team-provider-info.json に正しいリソース情報が格納されていない場合には、 UnhandledPromiseRejectionWarning: AccessDenied: Access Denied エラーが発生する。

AWS Amplify Framework(3)Authenticationカテゴリ

Authenticationカテゴリ

Authenticationカテゴリは、認証(AuthN)と認可(AuthZ)の機能を提供する。AWS Cognito ユーザプール を介して、FacebookやGoogleなどのOpenIDプロバイダーの情報を含むユーザ情報を格納し、ユーザの認証を行う。また、AWS Cognito Federated Identitiesを介して、例えば、S3へのファイルアップロードできる権限を付与するなど、AWSリソースに対しての認可の機能も提供する。AWS CLIは、アクセス制御ポリシーの自動化と、GraphQLを用いたきめ細やかなアクセス制御機能を提供する。

シンプルな認証では、AWS Cognito ユーザプール を通してユーザの認証のみを行い、この認証に通れば、(ログイン)アプリが利用するAWSリソースと通信が可能となる。一方で、ユーザ別にコンテンツを出し分ける必要がある場合などには、そのユーザに関連するAWSリソースのみにアクセス権限を付与しなければならない。この場合は、AWS Cognito Federated Identitiesを通して、そのユーザに必要な権限のみを許可された、AWS Credentialがやりとりされる。

セットアップ

Amplifyプロジェクトのルートディレクトリでamplify add authコマンドを実行することで、ウィザードに従って自動セットアップを行うことができる。

設定内容の例はこちら。

設定項目 内容
リソース名 myproject
User Pool名 myproject
Sign-Inに使用する属性 Email
MFA 無効
ユーザ登録等にEメールを使用 有効
認証メールのタイトル MyProject から 認証コード をお送りします
認証メールの本文 あなたの認証コードは {####} です。
Sign-Up時に必須の属性 Email, Name
Tokenの有効期間 30日
アクセスできるユーザ属性の限定 なし
その他の機能 ホワイトリストによるEmailドメインのフィルタ
OAuthの使用 なし
Lambda Triggers Pre Sign-up
ホワイトリストに指定するドメイン surbiton.jp

上の内容を設定するために、以下のような対話式ウィザードによって必要事項を埋めていく。

$ amplify add auth

 Do you want to use the default authentication and security configuration? Manual configuration
 Select the authentication/authorization services that you want to use: User Sign-Up & Sign-In only (Best used with a cloud API only)
 Please provide a friendly name for your resource that will be used to label this category in the project: myproject
 Please provide a name for your user pool: myproject
 Warning: you will not be able to edit these selections. 
 How do you want users to be able to sign in? Email
 Multifactor authentication (MFA) user login options: OFF
 Email based user registration/forgot password: Enabled (Requires per-user email entry at registration)
 Please specify an email verification subject: MyProject から 認証コード をお送りします
 Please specify an email verification message: あなたの認証コードは {####} です。
 Do you want to override the default password policy for this User Pool? No
 Warning: you will not be able to edit these selections. 
 What attributes are required for signing up? Email, Name
 Specify the app's refresh token expiration period (in days): 30
 Do you want to specify the user attributes this app can read and write? No
 Do you want to enable any of the following capabilities? Email Domain Filtering (whitelist)
 Do you want to use an OAuth flow? No
 Do you want to configure Lambda Triggers for Cognito? Yes
 Which triggers do you want to enable for Cognito (Press <space> to select, <a> to toggle all, <i> to invert selection)Pre Sign-up
 What functionality do you want to use for Pre Sign-up (Press <space> to select, <a> to toggle all, <i> to invert selection)Sign-Up email filtering (whitelist)
 Enter a comma-delimited list of allowed email domains (example: 'mydomain.com, myotherdomain.com'). surbiton.jp
Succesfully added the Lambda function locally
 Press enter to continue 
Successfully added resource myproject locally

Lambdaトリガー

Amplify CLIを用いることで、ホワイトリスト内のユーザのみに新規登録を認める処理を加えるなど、AWS Cognito ユーザプール のトリガに対応したLambdaを設定することができる。

Vue Components

Authカテゴリに関連して使用できるVueのUI Componentsは以下の通り。

Components 内容
<amplify-authenticator></amplify-authenticator> 認証全般
<amplify-sign-in></amplify-sign-in> Sign-In
<amplify-confirm-sign-in></amplify-confirm-sign-in> Sign-Inの確認
<amplify-sign-up></amplify-sign-up> Sign-Up
<amplify-forgot-password></amplify-forgot-password> パスワード忘れ時
<amplify-sign-out></amplify-sign-out> Sign-Out
<amplify-set-mfa></amplify-set-mfa> MFAの設定

認証画面の例

認証カテゴリを組み込んだログイン画面の実装例は以下の通り。

<template> ブロック

認証コンポーネント の詳細は、Authentication Components を参照。

<template>
  <div id="authenticator">
    <div v-if="signInStatus === 'signedOut'">
      <!-- 認証全般のコンポーネント -->
      <amplify-authenticator v-bind:authConfig="authConfig"></amplify-authenticator>
    </div>
  </div>
</template>

<script> ブロック

currentauthenticateduserメソッド の詳細は、 Amplify JavaScript library – Auth Class を参照。

<script>
// aws-amplify ライブラリの Auth カテゴリをインポート
import { Auth } from 'aws-amplify'
// aws-amplify-vue ライブラリの AmplifyEventBus カテゴリをインポート (イベントの発行とリッスン)
import { AmplifyEventBus } from 'aws-amplify-vue'

export default {
  name: 'Authenticator',
  components: {},
  // Vue - Amplify Plugin - Authentication Components
  // https://aws-amplify.github.io/docs/js/vue#authentication-components
  data: function() {
    return {
      signInStatus: 'signedOut',
      authConfig: {
        // Eメールによるサインイン
        usernameAttributes: 'Email',
        signUpConfig: {
          // サインアップ時の項目を一旦全て非表示にする
          hideAllDefaults: true,
          // サインアップ時の項目
          signUpFields: [
            {
              label: 'Email',
              key: 'email',
              required: true,
              displayOrder: 1,
              type: 'string',
              signUpWith: true
            },
            {
              label: 'Name',
              key: 'name',
              required: true,
              displayOrder: 2,
              type: 'string'
            },
            {
              label: 'Password',
              key: 'password',
              required: true,
              displayOrder: 3,
              type: 'password'
            },
          ]
        }
      }
    }
  },
  async beforeCreate() {
    try {
      // Amplify JavaScript library - Auth Class
      // https://aws-amplify.github.io/amplify-js/api/classes/authclass.html#currentauthenticateduser
      // ログインステータスの取得
      await Auth.currentAuthenticatedUser()
      this.signInStatus = 'signedIn'
    } catch (err) {
      this.signInStatus = 'signedOut'
    }
    // Vue - Amplify Plugin - AmplifyEventBus
    // authStateイベント のリッスン
    // https://aws-amplify.github.io/docs/js/vue#amplifyeventbus
    AmplifyEventBus.$on('authState', info => {
      switch (info) {
        case 'signedIn':
          this.signInStatus = 'signedIn'
          break
        default:
          this.signInStatus = 'signedOut'
          break
      }
    });
  }
}

<style> ブロック

<style>
  #authenticator {
    margin: auto;
    width: 460px;
  }
</style>

それ以外の画面に認証処理を追加する例

未認証のユーザにはページを表示させないように、ログイン後に表示される画面に認証処理を追加する例はこちら。

<script> ブロック

beforeCreate() でログイン状態を取得する。

<script>
export default { 
  name: 'UserTable', 
  // 使用するコンポーネント 
  components: {}, 
  // データ 
  data () { 
    // 必ず初期値が必要 
    return { 
      signInStatus: 'signedOut'
    } 
  },
  async beforeCreate() { 
    try { 
      // Amplify JavaScript library - Auth Class
      // https://aws-amplify.github.io/amplify-js/api/classes/authclass.html#currentauthenticateduser
      // ログインステータスの取得
      await Auth.currentAuthenticatedUser() 
      this.signInStatus = 'signedIn' 
    } catch (err) { 
      this.signInStatus = 'signedOut' 
    } 
    AmplifyEventBus.$on('authState', info => { 
      switch (info) { 
        case 'signedIn': 
          this.signInStatus = 'signedIn' 
          break 
        default: 
          this.signInStatus = 'signedOut' 
          break 
      } 
    }); 
  }
}
</script>

ローカライズ

標準の認証コンポーネントは、全て英語でメッセージが表示される。これらを 日本語対応 するためには、Amplifyの I18n カテゴリを使用して、main.js に以下の内容を追記する必要がある。

// 多言語対応
let languageDict = {
  ja:{
      // タイトル
      'Sign in to your account' : 'サインイン',
      'Create a new account': 'アカウントの新規作成',
      'Reset your password': 'パスワードをリセット',
      'Confirm Sign Up': 'メールアドレスの認証',
      // 入力項目
      'Username' : '会社のメールアドレス',
      'Email' : '会社のメールアドレス',
      'Enter your Email' : 'メールアドレスを入力してください',
      'Name' : '名前',
      'Password' : 'パスワード',
      'Enter your password' : 'パスワードを入力してください',
      'Code': '認証コード',
      'New Password': '新しいパスワード',
      'Confirmation Code': '認証コード',
      // 注釈
      'Forget your password? ' : 'パスワードを忘れた場合は ',
      'No account? ' : 'アカウントの作成は ',
      'Have an account? ': 'サインインは ', 
      'Lost your code? ': 'メールアドレスに認証コードが届きませんか? ', 
      // ボタン
      'Back to Sign In': 'サインイン',
      'Resend Code': '認証コードを再送信する',
      'Reset password' : 'パスワードを再設定',
      'Sign in' : 'こちら',
      'Sign In' : 'サインイン',
      'Sign Out' : 'サインアウト',
      'Create account' : 'こちら',
      'Create Account' : 'アカウントを作成',
      'Send Code': '次へ進む',
      'Submit': '送信',
      'Confirm': '登録完了',
      // エラーコード
      'Username cannot be empty': 'メールアドレスを入力してください',
      'null failed with error Generate callenges lambda cannot be called..': 'パスワードを入力してください',
      'Incorrect username or password.': 'メールアドレス もしくは パスワードが正しくありません',
      'Username/client id combination not found.': 'メールアドレスが正しくありません',
      'Invalid verification code provided, please try again.': '認証コードが正しくありません',
      'Password reset required for the user': 'パスワードを再設定してください'
  }
}
AmplifyModules.I18n.putVocabularies(languageDict)

AWS Amplify Framework(1)Amplifyの概要

AWS Amplify Frameworkとは

AWS Amplifyは、モバイルアプリやウェブアプリの実装を容易にするフレームワークで、AWS上のバックエンドをプロビジョニングし、iOSAndroidWeb、React Native上などのフロントエンドと簡単に統合することが可能なライブラリUIコンポーネントCLIなどを提供する。バックエンドのサービスを設定可能なAmplify CLIや、Web上に展開するAmplify JSなどのリソースがGitHub上で提供されており、認証解析プッシュ通知ボットなどの機能を実装することが可能である。

Amplify Frameworkは、カテゴリベースのプログラミングモデルを採用しており、対話式の設定画面から各カテゴリを追加/編集/削除することができる。

機能名 Frontend API Backend Category AWSサービス 内容
Analytics AnalyticsClass analytics Pinpoint ユーザのセッションや属性などを計測
Interactions Interactions intaraction Lex Botの構築
Cache CacheObject LRUキャッシュ
API APIClass api Lambda + API Gateway REST/GraphQL APIの利用
PubSub PubSub IoT リアルタイムデータのやりとり
Hub HubClass ユーザセッション、属性等を追跡
Authentication AuthClass auth Cognito 認証APIとpre-build UI component
Notification PushNotification notifications Pinpoint プッシュ通知
I18n I18n 多言語化
Storage StorageClass storage S3, DynamoDB 静的コンテンツの管理
XR XR xr Sumerian AR/VR
Logger Logger コンソールログの記録
Service Worker ServiceWorkerClass
function Lambda 関数の作成
hosting S3, CloudFront Webサイトホスティング
Predictions prediction Recognition など 予測

Amplify CLI

Amplify CLIを用いることでバックエンドを簡単に設定することができる。バックエンドのカテゴリごとにカテゴリプラグインや、プロバイダープラグインフロンドエンドプラグインなど様々なプラグインが用意されている。これらのリソースの状況は、amplify statusコマンドで確認することができる。

初期設定

amplify initコマンドを実行することで、フロントエンドの設定確認と初期化、AWS上のバックエンドをセットアップすることができる。このとき、CloudFormation経由で IAMロールやS3バケットの作成 も行われる。

コマンド 実行内容 備考
amplify init Amplify プロジェクトを作成/初期化, IAMロールの作成 ルートディレクトリで実行すること
amplify delete Amplify プロジェクトをすべて削除 再度構築する場合は amplify init が必要

コマンドの実行手順は以下の通り。

実行順序 コマンド 内容
1 amplify configure AWSユーザや認証情報の設定
2 amplify init プロジェクトの作成
3 amplify add カテゴリの追加
4 amplify push バックエンドのデプロイ

バックエンドの環境設定

1つのプロジェクトは設定の異なる複数のバックエンド(=Env)を持つことが可能で、amplify envコマンドを用いてこれらのバックエンドを切り替えることが可能。Gitのブランチと組み合わせることも可能で、masterブランチ上のプロジェクトはprod環境のバックエンド上にデプロイ、developブランチ上のプロジェクトはdevelop環境のバックエンド上にデプロイするなどの設定を行うことができる。万が一、AWS上のCloudFormationを削除してしまった状態のままデプロイした場合はエラーとなるので、この場合はamplify initコマンドでバックエンドの再生成が必要となる。

コマンド 実行内容
amplify env add <ENV> バックエンドを追加
amplify env remove <ENV> バックエンドを削除
amplify env pull <ENV> –restore AWS上のバックエンド設定を参照して上書き
amplify env ckeckout <ENV> –restore 指定した環境設定を適用
amplify env list バックエンドの一覧を表示

AWS Amplify Console等の外部サービスでAmplifyをデプロイしたあとに、amplify pushコマンドを用いて開発環境上でデプロイを実行すると、バックエンドのデプロイ状態に差異が生じているためにデプロイに失敗する。上記のamplify env pullコマンドによって、AWS上の最新のバックエンド情報を取得することで、この問題は解決する。

カテゴリの追加と削除

上述のようにAmplify Frameworkは、認証解析などの様々な機能を有している。これらの機能(=カテゴリ)を自身のプロジェクトに追加したり削除したりするのが以下のコマンドである。

コマンド 実行内容
amplify add <CATEGORY> カテゴリを追加
amplify update <CATEGORY> カテゴリを更新
amplify remove <CATEGORY> カテゴリを削除

その他のコマンド

その他よく使うコマンドは以下の通り。

コマンド 実行内容
amplify status Amplify プロジェクトのステータスを表示
amplify push Amplify プロジェクトをAWS上でデプロイ
amplify pull AWSから設定情報を取得し、ローカル環境を変更
amplify console AWSのマネージメントコンソールに遷移
amplify delete Amplify プロジェクトを削除

Amplifyプロジェクト

Amplifyプロジェクトは、以下のようなディレクトリ構成となっている。

.
├── amplify/
│   ├── .config/                        (自動生成)   クラウドの構成とユーザー設定を格納 (amplify init)
│   │   ├── local-aws-info.json         (自動生成)  AWSクレデンシャルのプロファイル名を格納
│   │   ├── local-env-info.json         (自動生成)  ローカルのディレクトリやIDEの設定を格納
│   │   └── project-config.json         (自動生成)  プロジェクトの設定を格納       
│   ├── backend/
│   │   ├─── api
│   │   │   └── PROJECT_NAME
│   │   │       └── schema.graphql      (編集可)    GraphQLのスキーマ
│   │   ├─── auth
│   │   │   └── PROJECT_NAME
│   │   │       └── parameters.json     (編集可)    プロンプトで設定した内容を格納(amplify add auth)
│   │   ├── amplify-meta.json          (自動生成)   AWSリソースの設定情報(Permission, Category)を格納, Gitリポジトリの管理対象外
│   │   └── awscloudformation          (自動生成)   CloudFormationのルートスタック, Gitリポジトリの管理対象外   
│   ├──  #current-cloud-backend/       (自動生成)  直近に取得したクラウド構成, Gitリポジトリの管理対象外
│   └──  team-provider-info.json       (自動生成)  Environment設定(Permission, Category, CloudFormation Stack)を格納
└──  src/
    ├── App.vue                         (編集可)     Vueの単一コンポーネントファイル   
    ├── aws-exports.js                  (自動生成)   AWSリソースのエンドポイント等の情報を格納, Gitリポジトリの管理対象外 (amplify init)
    ├── components/                     (手動生成)   作成したVueコンポーネント
    │    ├── Authenticator.vue         (自動生成)   認証画面コンポーネント
    │    └── Main.vue                  (手動生成)   メインコンポーネント
    ├── graph/                          (自動生成)   GraphQL statement
    │    ├── mutation.js               (自動生成)   
    │    ├── queries.js                (自動生成)   
    │    ├── schema.json               (自動生成)   
    │    └── subcriptions.js           (自動生成)   
    ├── main.js                         (編集可)     Vueのエントリーポイント 
    ├── package.json                    (自動生成)   依存関係のあるライブラリの一覧
    └── router/                         (手動生成)   ルータコンポーネント
         └── index.js                  (手動生成)