AWS
AWS Cognito を PHP SDK で操作する ~ユーザ作成~

ユーザ管理を楽にしたい

自前のMySqlサーバなどを使ってユーザ管理でやっていたことをAWS Cognito に切り替えようかなと

ということで、勉強しつつ備忘録として残しておこうかと

とりあえず、今回はこんな感じでまとめておく

1.Cognito とは?

AWS Cognito

Amazon Cognito を使用すれば、ウェブアプリケーションおよびモバイルアプリに素早く簡単にユーザーのサインアップ/サインインおよびアクセスコントロールの機能を追加できます。

とのこと

個人的に感じたメリット

  • ソーシャルID(Googleなど)を使ったサインアップも設定できる
  • 2段階認証も簡単に設定できる
  • AWSのUIを使って簡単に登録もできる
  • 不正アクセスなどによるアカウントロックもついている
  • 無料分もわりかしついているので学習もしやすい

てな感じだろうか。とりあえず、やって慣れろの精神でやってみる

2.Cognitoを設定して、AWSのUIを使って更新

めっちゃ単純なものをとりあえず作成してみる

  1. ユーザープールを設定して作る
  2. AWSのUIを使用してユーザーを登録する

この二つ。といっても手順はそれなり

ユーザープールを設定して作る

1・cognito にアクセスして、まずはユーザープールを作成を選択。新しいUIデザインが公開されていたので、そちらを使用。サインインエクスペリエンスの設定は、今回はEメールだけチェックを入れる。次へ

2・セキュリティ要件では、多要素認証のMFA設定をなしにする。ちなみに使う時はCognitoが用意してくれるUIでは使用できないので、APIを使う必要が出てくる。パスワードの設定が面倒な場合はカスタムで簡単な設定に変えておくといい。設定後次に進む

3・サインアップエクスペリエンスを設定では、自己登録とcognitoが検証と〜 にチェックを入れておく。今回は簡単にしておくので、Eメールの送信と受け取りにチェックをいれ、次に進む。

4・アプリケーションを統合 では、ユーザープール名を入力し、Cognito のホストされた UI を使用にチェックを入れる。入れるとドメインのフォームが追加されるので、Cognitoドメインを使用するにして、Cognitoドメインに使用可能な任意のドメインを入力する

5・最初のアプリケーションクライアント では、今回はパブリッククライアントを選択、クライアント名を入力、クライアントのシークレットを生成しない、にする。コールバックURLを入力する。発行された認証コードを受け取るURLで、localhostでもよい。次に進み、確認および作成の画面で確認後、ユーザープールを作成ボタンで作成を行う

AWSのUIを使用してユーザーを登録する

1・作成後、プール一覧画面に飛ぶので、作成したプールを選択後、アプリケーションの統合タブを選択 → アプリクライアントと分析にあるクライアント名をクリック → ホストされたUIを表示 の順に進む。進むと、AWSで用意してくれたUIが表示されるので、Sign Upを選択。e-mailとパスワード(パスワードの制限は先ほど作成したルール)を入力して、Sign UP

2・コード確認画面に進み、しばらくすると入力したメールアドレスに確認コードがくるので、コードを入力する。成功するとコールバックで設定したURLにリダイレクトする。また、ユーザープールに移動して、ユーザタブに移動するとユーザーが作成されているのがわかる。

3.SDK for PHP を使用してユーザーを作成する

ということで、最終的な今回の目標である SDK for PHP を使用して、API経由で登録まで行う。

使用/参考したAWS記事

今回はZipで落として直接設置するので、「インストール:AWS SDK for PHPバージョン 3」ページ下部の「ZIP ファイルを使用したインストール」のリンクからファイルを直接落として解凍したフォルダを設置する。

また、credentialは、IAMでcognitoの権限を持ったユーザを作成し、アクセスキーとシークレットキーを用意しておく。サンプルを元にコードを以下の様にしてみた


<? php
	
	#パスは環境に合わせて直す
	require '../aws/aws-autoloader.php';
	use Aws\CognitoIdentityProvider\CognitoIdentityProviderClient;
	use Aws\Exception\AwsException;


	$config = [
	  'version' => 'latest',
	  'region' => 'ap-northeast-1',
	  
	  #sampleのように設定ファイルを読み込むと失敗したので、直接キーを指定する方法に変更
	  'credentials' => [
        'key' => 'aws_access_key_id',
        'secret' => 'aws_secret_access_key'
		]
	];
	
	$client = new CognitoIdentityProviderClient($config);
	
	#先ほど作ったユーザープールの画面からプールIDをコピーして貼り付ける。ユーザープールの概要に記載がある
	$userPoolId = "PoolIdはここ";
	
	#登録するメールアドレス
	$verification_email = "sample@sample.com";


try {
    $result = $client->adminCreateUser([
        'UserPoolId' => $userPoolId, 
        'Username' => $verification_email
    ]);
    
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    echo $e->getMessage() . "\n";
    error_log($e->getMessage());
}

?>

credential情報を .awsに入っているファイルやiniファイルを指定やってみても失敗したので、直接指定する方法にした。

ユーザーIDでログインを許可せず、必須の項目がE-mailの場合、Username の値はE-mailとなる。たとえば、名前とe-mailどちらもログインが可能に設定して二つを必須項目に選んでいる場合は、Usernameには、テキスト(mailのフォーマットだとエラーになる)を入れる必要がある。e-mailは、UserAttributesで入れる必要がある。

今回はe-mailのみのログインでe-mailを必須項目として設定したので、ユーザー名にはcognitoから与えられる一意のID(sub)が入力される。それでは困る場合、UserAttributes で属性名と値を指定すれば入る。ただ、awsのサンプルのままではエラーが出るので、注意。正しい連想配列で入れる。また、電話番号など元から用意されている属性では、フォーマットが決まっている(電話番号は、+810123456789 のような国番号を追加した形でないとエラーになる)ので注意が必要

以下名前と電話番号追加バージョン


<? php
	
	#パスは環境に合わせて直す
	require '../aws/aws-autoloader.php';
	use Aws\CognitoIdentityProvider\CognitoIdentityProviderClient;
	use Aws\Exception\AwsException;


	$config = [
	  'version' => 'latest',
	  'region' => 'ap-northeast-1',
	  
	  #sampleのように設定ファイルを読み込むと失敗したので、直接キーを指定する方法に変更
	  'credentials' => [
        'key' => 'aws_access_key_id',
        'secret' => 'aws_secret_access_key'
		]
	];
	
	$client = new CognitoIdentityProviderClient($config);
	
	#先ほど作ったユーザープールの画面からプールIDをコピーして貼り付ける。ユーザープールの概要に記載がある
	$userPoolId = "PoolIdはここ";
	
	#登録するメールアドレス
	$verification_email = "sample@sample.com";


try {
    $result = $client->adminCreateUser([
        'UserPoolId' => $userPoolId, 
        'Username' => $verification_email,
        
        ##追加
        'UserAttributes' => [
	        [
	            'Name' => 'name',
	            'Value' => 'hogehoge',
	        ],
	        [
	            'Name' => 'phone_number',
	            'Value' => '+810123456789',
	        ]
	    ]
    ]);
    
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    echo $e->getMessage() . "\n";
    error_log($e->getMessage());
}

?>

成功すれば、メールでパスワードが飛んでくる。メッセージのフォーマットは、ユーザープールのメッセージングタブにあるテンプレートより変更が可能。

作成は成功したので、次回以降、ログイン、ログイン状態の確認やログアウトを調べる