はじめてのサーバーレス ~ サーバーレスな会員制サイトを作ってみよう ~ 第 2 回

2021-01-05
How to be a Developer

亀田 治伸

この記事では、以下のサーバーレス系サービスを活用し、簡易的な会員制サイトにログインしたユーザーが自分のデータを登録できる、という環境をつくる Step by Step ガイドをお届けします。少し記事の分量が多いので、数回に分けて連載を予定していますのでお付き合いください。

この記事は第二回目です。はじめてこのハンズオンに挑む方は第一回から始めてください。

ご注意

本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。

*ハンズオン記事およびソースコードにおける免責事項 »

このクラウドレシピ (ハンズオン記事) を無料でお試しいただけます »

毎月提供されるクラウドレシピのアップデート情報とともに、クレジットコードを受け取ることができます。 


1. API Gateway を追加して動作確認を行う

1-1. API Gateway REST API 作成

AWS マネジメントコンソールのサービス一覧から [API Gateway] を選択します。

クリックすると拡大します

[API タイプを選択] の中から [REST API][構築] をクリックします。
[REST API プライベート] の方ではありませんので注意してください

クリックすると拡大します

初めて API Gateway を利用する場合は下図のダイアログが表示されますので、[OK] をクリックします。

クリックすると拡大します

[新しい API の作成] の選択肢では [新しい API] を選択します。

[API 名] 欄の入力ができるようになるので、[YYYYMMDDserverless] と入力します。(YYYYMMDD は本日の日付)

[エンドポイントタイプ][リージョン] のままにします。

上記の設定が終わったら、[API の作成] をクリックします。

クリックすると拡大します

作成した API の画面になりますので、[アクション] プルダウンから [リソースの作成] を選択します。

クリックすると拡大します

[リソース名] 欄に [items] と入力します。
[リソースパス] 欄は [リソース名] 欄と同じ内容が自動的に入力されますので、そのままにします。

入力したら、[リソースの作成] をクリックします。

クリックすると拡大します

リソース [/items] が作成されました。

クリックすると拡大します

1-2. API に GET メソッドを追加

[/items] リソースの画面で、[アクション] プルダウンから [メソッドの作成] を選択します。

クリックすると拡大します

メソッド種類のプルダウンから [GET] を選択して、右側のチェックボタンをクリックします。

クリックすると拡大します

[統合タイプ] はデフォルトの [Lambda 関数] のままにします。

[Lambda プロキシ統合の使用] のチェックは外したままにします。

[Lambda 関数] 欄に、前節で作成した Lambda 関数のうち「Read」の方の関数名を入力します。(関数名の一部、例えば [YYYYMMDD] を入力すると候補が表示されて容易に入力できます) (Read と Write は間違えやすいので注意です)

クリックすると拡大します

クリックすると拡大します

[保存]を押すと、権限追加の確認ダイアログが表示されますので、[OK] をクリックします。

クリックすると拡大します

作成した [GET] メソッドの画面になりますので、[メソッドリクエスト] をクリックします。

クリックすると拡大します

[URL クエリ文字列パラメータ] をクリックして展開します。

クリックすると拡大します

[クエリ文字列の追加] をクリックします。

クリックすると拡大します

[名前] 欄に [artist] と入力して、右端のチェックボタンをクリックします。

クリックすると拡大します

画面上部の [←メソッドの実行] をクリックして、前の画面に戻ります。

クリックすると拡大します

[統合リクエスト] をクリックします。

クリックすると拡大します

一番下の [マッピングテンプレート] をクリックして展開します。

クリックすると拡大します

[テンプレートが定義されていない場合 (推奨)] を選択します。

[マッピングテンプレートの追加] をクリックします。

クリックすると拡大します

[Content-Type] 欄に [application/json] と入力して、右側のチェックボタンをクリックします。(タイプミスに注意 !)

クリックすると拡大します

[apigateway_get_mapping.txt] の内容をコピーしてテンプレートの入力欄にペーストします。

入力したら [保存] をクリックします。(画面は変わりません)

クリックすると拡大します

画面上部の [←メソッドの実行] をクリックして、前の画面に戻ります。

クリックすると拡大します

[テスト] をクリックします。

クリックすると拡大します

[クエリ文字列] 欄に [artist=Michael Jackson] と入力します。

クリックすると拡大します

[テスト] をクリックすると、右側に結果が表示されます。

[ステータス][200] と表示されていれば成功です。

[レスポンス本文] に DynamoDB テーブルの内容が表示されていることを確認してください。
 

クリックすると拡大します

1-3. API に POST メソッドを追加

リソースのツリー階層から [/items] をクリックして選択します。

クリックすると拡大します

[アクション] プルダウンから [メソッドの作成] を選択します。

クリックすると拡大します

メソッド種類のプルダウンから [POST] を選択して、右側のチェックボタンをクリックします。

クリックすると拡大します

[統合タイプ] はデフォルトの [Lambda 関数] のままにします。

[Lambdaプロキシ統合の使用] のチェックは外したままにします。

[Lambda 関数] 欄に、前節で作成した Lambda 関数のうち「Write」の方の関数名を入力します。

 

クリックすると拡大します

[保存] を押すと権限追加の確認ダイアログが表示されますので、[OK] をクリックします。

クリックすると拡大します

作成した [POST] メソッドの画面になりますので、[統合リクエスト] をクリックします。

クリックすると拡大します

一番下の [マッピングテンプレート] をクリックして展開します。

クリックすると拡大します

[テンプレートが定義されていない場合 (推奨)] を選択します。

[マッピングテンプレートの追加] をクリックします。

クリックすると拡大します

[Content-Type] 欄に [application/json] と入力して、右側のチェックボタンをクリックします。

クリックすると拡大します

[apigateway_post_mapping.txt] の内容をコピーしてテンプレートの入力欄にペーストします。

[保存] をクリックします。(画面は変わりません)

クリックすると拡大します

画面上部の [←メソッドの実行] をクリックして、前の画面に戻ります。

クリックすると拡大します

[テスト] をクリックします。

クリックすると拡大します

[apigateway_post_test.txt] の内容をコピーして [リクエスト本文] 欄にペーストします。

クリックすると拡大します

[テスト] をクリックすると、右側に結果が表示されます。

[ステータス] [200] と表示されていれば成功です。

クリックすると拡大します

DynamoDBの画面に移動して、テーブルの [項目] タブを表示します。

リロードボタンをクリックして、POST メソッドから呼び出された Lambda 関数によって書き込まれたデータが表示されていることを確認します。

クリックすると拡大します

1-4. CORS の設定

リソースのツリー階層から [/items] をクリックして選択します。

クリックすると拡大します

[アクション] プルダウンから [CORS の有効化] を選択します。

クリックすると拡大します

[CORS を有効にして既存の CORS ヘッダーを置換] をクリックします。

クリックすると拡大します

確認ダイアログが表示されますので、[はい、既存の値を置き換えます] をクリックします。

クリックすると拡大します

CORS の有効化処理が実行されて、すべての結果に緑のチェックが付くことを確認します。

クリックすると拡大します

画面左側のメニューから [ゲートウェイのレスポンス] をクリックします。

クリックすると拡大します

一番上の [アクセスが拒否されました] を選択して、画面右上の [編集] をクリックします。

クリックすると拡大します

[レスポンスヘッダーの追加] をクリックします。

クリックすると拡大します

以下の通り入力します。

  • レスポンスヘッダー : [Access-Control-Allow-Origin] と入力
  • 値 : [‘*’] と入力 (シングルクォーテーション、アスタリスク、シングルクォーテーション)

[保存] をクリックします。

クリックすると拡大します

1-5. API のデプロイ

リソースのツリー階層から [/] をクリックして選択します。

クリックすると拡大します

以下の通り入力します。

  • デプロイされるステージ : [新しいステージ] を選択
  • ステージ名 : [demo] と入力
  • ステージの説明 : (省略)
  • デプロイメントの説明 : (省略)

上記が終わったら、[デプロイ] をクリックします。

クリックすると拡大します

デプロイが行われ、ステージ [demo] の画面が表示されます。
画面上部には API を呼び出す際の URL が表示されています。(後の手順で使用するためメモしておいてください)

クリックすると拡大します

[SDK の生成] タブをクリックします。

[プラットフォーム][JavaScript] を選択して、[SDK の生成] をクリックします。

ファイル [javascript_YYYY-MM-DD_HH-MMZ.zip] のダウンロードが行われるので、任意の場所に保存します。(後の手順で使用します)

クリックすると拡大します

1-6. Cloud9 からの動作確認

AWS Cloud9 が利用できない場合、こちらのブログ をご参考に AWS IDE Toolkits または AWS CloudShell をご利用ください。

AWS Cloud9 から AWS IDE Toolkits または AWS CloudShell に移行する方法 »

Cloud9 の画面へ移動します。

時間が経っている場合には Cloud9 の EC2 インスタンスが停止している可能性があります。その際は、Web ブラウザをリロードするか、一旦画面を閉じて Cloud9 の管理画面を開き、対象の Cloud9 環境を指定して [Open IDE] をクリックしてください。

 

クリックすると拡大します

Cloud9 の画面下部にある [Terminal] ウィンドウを使用してコマンドを実行します。
画面が狭い場合は、境界線をドラッグして画面を大きくして頂いて構いません。

クリックすると拡大します

ここからの一連のコマンド実行内容は、[apigateway_curl_test.txt] にも記載していますので参考にしてください。

まず、前節で確認した [API 呼び出し URL] を環境変数にセットします。(URL はご自身の環境に合わせて入力してください)

$ export API_URL=https://XXXXXXXXXX.execute-api.AWS_REGION.amazonaws.com/demo

GET メソッドの動作を確認します。
以下のようにコマンドを入力します。

$ curl -X GET -i ${API_URL}/items?artist=Michael+Jackson

API 呼び出しに成功すると、以下のように結果が返ってくるはずです。

$ curl -X GET -i ${API_URL}/items?artist=Michael+Jackson
$ curl -X GET -i ${API_URL}/items?artist=Michael+Jackson
HTTP/2 200 
date: Tue, 1 Sep 2020 05:15:01 GMT
content-type: application/json
content-length: 49
x-amzn-requestid: 4c75f8ea-fc5b-47f7-a323-799bc98d7664
access-control-allow-origin: *
x-amz-apigw-id: Sr4pIEKSNjMFqIg=
x-amzn-trace-id: Root=1-5f5b07d3-5154bf8e204e3de2231150b5;Sampled=0

[{"Title":"Thriller","Artist":"Michael Jackson"}]

POST メソッドの動作を確認します。
以下のようにコマンドを入力します。

$ curl -X POST -i \
  -H 'Content-Type: application/json' \
  -d '{"artist":"Michael Jackson","title":"Billie Jean"}' \
  ${API_URL}/items

API 呼び出しに成功すると、以下のように結果が返ってくるはずです。

$ curl -X POST -i \
  -H 'Content-Type: application/json' \
  -d '{"artist":"Michael Jackson","title":"Billie Jean"}' \
  ${API_URL}/items
$ curl -X POST -i \
>   -H 'Content-Type: application/json' \
>   -d '{"artist":"Michael Jackson","title":"Billie Jean"}' \
>   ${API_URL}/items
HTTP/2 200 
date: Tue, 1 Sep 2020 05:17:42 GMT
content-type: application/json
content-length: 2
x-amzn-requestid: 0eaf5dac-0ae8-4790-9556-5d314083b5be
access-control-allow-origin: *
x-amz-apigw-id: Sr5CXHOjtjMFuTQ=
x-amzn-trace-id: Root=1-5f5b0875-0a3206c732fed15649481e99;Sampled=0

{}

DynamoDB の画面に移動して、テーブルの [項目] タブを表示します。

リロードボタンをクリックして、POST メソッドから呼び出された Lambda 関数によって書き込まれたデータが表示されていることを確認します。

クリックすると拡大します

1-7. Webブラウザからの動作確認

[webpage] フォルダに以下のファイルを [427] のフォルダからコピーします。

  • [apigateway.html]
  • [apigateway.js]


1-5. API のデプロイ」でダウンロードした [javascript_YYYY-MM-DD_HH-MMZ.zip] をzip展開します。

展開して出来たフォルダ [apiGateway-js-sdk] の直下に [apigClient.js] というファイルがあります。

このファイルを [webpage]-[lib]-[apigateway] フォルダの直下にコピーします。


この時点で、[webpage] フォルダ配下の構成は以下のようになっているはずです。

[website]
┣ [img] … アイコン等の画像ファイル
┣ [lib] … 各種ライブラリ/SDK (必要なものを格納済み、ただし apigClient.js を除く)
┃  ┣ [apigateway]
┃  ┃  ┣ [lib]
┃  ┃  ┗ apigClient.js … API Gateway アクセスクライアントのクラス定義
┃  ┣ [awssdk]
┃  ┗ [cognito]
┣ [style] … CSS ファイル
┣ apigateway.html … Web ブラウザで表示するページ
┗ apigateway.js   … API Gateway へアクセスを行う処理を記述した JavaScript コード

その他のファイルは存在していても邪魔にはならないので無視します。(後ほど使います。)

[apigateway.html] を Web ブラウザで開きます。

クリックすると拡大します

まず、GET メソッドを試します。

[Artist] 欄に検索する文字列を入力して、[Run] をクリックします。

クリックすると拡大します

[Status Code] 欄に [200] と表示されることを確認します。

[Response Data] 欄に GET メソッドの結果が表示されていることを確認します。

クリックすると拡大します

続いて POST メソッドを試します。

[Artist] 欄および [Title] 欄に登録するデータを入力して、[Run] をクリックします。

クリックすると拡大します

[Status Code] 欄に [200] と表示されることを確認します。

DynamoDB の画面から、登録したデータが正しく書き込まれていることを確認します。

クリックすると拡大します


2. Cognito の動作確認を行う

2-1. Cognito ユーザープールの作成

AWS マネジメントコンソールのサービス一覧から [Cognito] を選択します。

[ユーザープールの管理] をクリックします。

クリックすると拡大します

[ユーザープールを作成する] をクリックします。

クリックすると拡大します

[プール名] 欄に [YYYYMMDDserverless] と入力します。(YYYYMMDD は本日の日付)

[デフォルトを確認する] をクリックします。

クリックすると拡大します

画面左側のメニューから [ポリシー] を選択します。

クリックすると拡大します

[数字を必要とする][特殊文字を必要とする][大文字を必要とする][小文字を必要とする] の各項目のチェックを全て外します。(これはテスト目的です。運用環境では強固なポリシーを設定してください)

画面下部の [変更の保存] をクリックします。

クリックすると拡大します

画面左側のメニューから [アプリクライアント] を選択します。

クリックすると拡大します

[アプリクライアントの追加] をクリックします。

クリックすると拡大します

[アプリクライアント名] 欄に [JavaScript App] と入力します。

[クライアントシークレットを生成] のチェックを外します。

上記が終わったら、[アプリクライアントの作成] をクリックします。

クリックすると拡大します

画面左側のメニューから [確認] を選択します。

クリックすると拡大します

確認画面になりますので、[プールの作成] をクリックします。

クリックすると拡大します

ユーザープールが作成されました。ユーザープールの [プールID] が表示されています。(後の手順で使用するためメモしておいてください)

クリックすると拡大します

画面左側のメニューから [アプリクライアント] を選択します。

[アプリクライアントID] が表示されています。(こちらも後の手順で使用するためメモしておいてください)

クリックすると拡大します

Cognito ID プールの作成

[Cognito] 画面で、[ID プールの管理] をクリックします。

クリックすると拡大します

[ID プール名] 欄に [YYYYMMDDserverless] と入力します。(YYYYMMDD は本日の日付)

[認証されていない ID に対してアクセスを有効にする] にチェックを入れます。

クリックすると拡大します

[認証プロバイダー] をクリックして展開します。

クリックすると拡大します

[Cognito] タブが選択されていることを確認します。(これは「Cognito ユーザープールを認証プロバイダーとして利用する」ということを意味します)

[ユーザープール ID] および [アプリクライアント ID] 欄に、前手順で確認したユーザープールの各 ID を入力します。

上記ののち、[プールの作成] をクリックします。

クリックすると拡大します

Cognito のウィザードが自動的に IAM ロールを作成することに対して許可を求められます。

[詳細を表示] をクリックして展開します。

クリックすると拡大します

2 つのロール [Cognito_YYYYMMDDserverlessAuth_Role] (認証された ID 用のロール) および [Cognito_YYYYMMDDserverlessUnauth_Role] (認証されていない ID 用のロール) が作成されることを確認します。

[許可] をクリックします。

クリックすると拡大します

ID プールが作成されました。

[AWS 認証情報の取得] のサンプルコードに [ID プールの ID] が記述されています。(後の手順で使用するためメモしておいてください)

クリックすると拡大します

2-3. Web ブラウザからの動作確認

[webpage] フォルダに「1. API Gateway を追加して動作確認を行う」で使用したファイルが残っていると思います。[433] のフォルダからファイルを [webpage] の下にコピーします。

[webpage] フォルダに以下のファイルがあります。

  • [cognito.js]
  • [config.js]
  • [login.html]
  • [mypage.html]

[config.js] をテキストエディタで開きます。
[userPoolId][appClientId][identityPoolId] の各値を、前節・前々節で確認した [ユーザープール ID][アプリクライアント ID][ID プール ID] の値にそれぞれ書き換えます。
※ 東京以外のリージョンを利用している場合は、[region] の値も併せて書き換えてください

const CognitoConfig = {
    region: 'ap-northeast-1',

    // User Pool
    userPoolId: 'ap-northeast-1_XXXXXXXXX',
    appClientId: 'XXXXXXXXXXXXXXXXXXXXXXXXXX',

    // Federated Identity
    identityPoolId: 'ap-northeast-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
}

この時点で、[webpage] フォルダ配下の構成は以下のようになっているはずです。
その他のファイルは存在していても邪魔にはならないので無視します。(後ほど使います。)

[website]
┣ [img] … アイコン等の画像ファイル
┣ [lib] … 各種ライブラリ /SDK (必要なものを格納済み、ただし apigClient.js を除く)
┃  ┣ [apigateway]
┃  ┃  ┣ [lib]
┃  ┃  ┗ apigClient.js … API Gateway アクセスクライアントのクラス定義
┃  ┣ [awssdk]
┃  ┗ [cognito]
┣ [style] … CSS ファイル
┣ cognito.js  … Cognito へアクセスを行う処理を記述した JavaScript コード
┣ config.js   … Cognito の ID 情報等を記述したファイル
┣ login.html  … Web ブラウザで最初に表示するページ
┗ mypage.html … ログイン処理が行われた後に遷移する Web ページ

[webpage] フォルダ直下の [login.html] を Web ブラウザで開きます。

クリックすると拡大します

画面上部に「Cognito ID プールによって現在のブラウザセッションに割り当てられた IAM ロール」の情報が表示されています。

まだ認証が行われていませんので [Cognito_YYYYMMDDserverlessUnauth_Role] が割り当てられていることが分かります。

クリックすると拡大します

まず、サインアップ (ユーザー登録) を行います。

ユーザー名、パスワード、メールアドレスを入力して、[Sign-up] をクリックします。
※ 確認メールが送信されますので、受信可能なメールアドレスを指定してください。

クリックすると拡大します

[Result] 欄にエラーが出力されたりせず、下図のように表示されればサインアップ成功です。

クリックすると拡大します

AWS マネジメントコンソールで Cognito ユーザープールの画面を開き、[ユーザーとグループ] を選択します。

サインアップを行ったユーザーが登録されていることが確認できます。(表示されない場合は、右上のリロードボタンをクリックして表示を更新してください)

アカウントのステータスが [UNCONFIRMED] (未確認) であることを確認してください。

クリックすると拡大します

こちらのような確認メールが届いていることを確認します。

[confirmation code] (確認コード、6 桁の数字) は次の手順で必要になります。

クリックすると拡大します

次に、アクティベーション (メールアドレスによる本人確認) を行います。

ユーザー名、および、メールで送られてきた [confirmation code] を入力して、[Activete] をクリックします。

クリックすると拡大します

[Result] 欄に [success] と表示されればアクティベーション成功です。

クリックすると拡大します

Cognito ユーザープールの [ユーザーとグループ] 画面で、リロードして表示を更新します。

アカウントのステータスが [CONFIRMED] (確認済み) に変わっていることを確認します。

クリックすると拡大します

ユーザーがアクティベートされましたので、サインイン (ログイン) を行います。

ユーザー名とパスワードを入力して、[Sign-in] をクリックします。

クリックすると拡大します

サインインが成功すると、[My Page] に遷移します。

クリックすると拡大します

My Pageにおいても、画面上部に「Cognito ID プールによって現在のブラウザセッションに割り当てられた IAM ロール」の情報が表示されます。

認証が行われましたので [Cognito_YYYYMMDDserverlessAuth_Role] が割り当てられています。

クリックすると拡大します

[About current user] には、Cognito ユーザープールから現在のブラウザセッションが取得した情報が表示されています。

  • Reference username
  • Identity Token
  • ID Token Expiration
  • Access Token

画面を一番下までスクロールすると [Sign-out] ボタンがあります。

サインアウトすると [Login Page] に戻ります。

クリックすると拡大します


5. まとめ

今日はページの関係でここまでです。なるべく早く第三回を出しますので、楽しみにお待ちください。

今日作った環境は継続的な課金は発生しませんので残しておいてください。

まだまだハンズオンは続きます!


builders.flash メールメンバーへ登録することで
AWS のベストプラクティスを毎月無料でお試しいただけます

プロフィール

亀田 治伸
アマゾン ウェブ サービス ジャパン合同会社 エバンジェリスト

兵庫県伊丹市出身。米国州立南イリノイ大学卒業。
認証系独立 ASP 、動画・音楽配信システム構築、決済代行事業者を経て現職。ユーザー視点に立ったわかりやすい AWS のサービス解説を心掛ける。
AWS のどんなサービスでも 1 分づつ資料なしで説明することができる、という特技を持つ自称【AWSマニア】

AWS を無料でお試しいただけます

AWS 無料利用枠の詳細はこちら ≫
5 ステップでアカウント作成できます
無料サインアップ ≫
ご不明な点がおありですか?
日本担当チームへ相談する