AWS
AWS Cognito を PHP SDK で操作する ~認証~

今回は認証をまとめる

前回四苦八苦しながら作成したプールにAPIを使用してPHPから登録を行うことができた。が、初回パスワード変更や、一意キーの確認、ログイン状態の確認などをしないと使えない。今回は、その辺をまとめる

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

1.初回パスワード変更

前回の「AWS Cognito を PHP SDK で操作する ~ユーザ作成~」で作成したユーザでは、確認ステータスが「パスワードを強制的に変更」になっている。与えられたパスワードは、時限で使用できなくなってしまうため、初回ログイン時に任意のパスワードにしてもらう必要がある。

とりあえず、CognitoIdentityProviderClient の adminGetUser で usernameキー(前回メアドで作成しているのでメアド)とUserPoolIDを指定すればステータスを確認できるのでしてみる。


<? 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はここ";
	
	#登録したメールアドレス
	$email = "sample@sample.com";
	
    $client = new CognitoIdentityProviderClient($config);
    

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

?>

いろいろ情報が返ってくる。作成時だと、 ["UserStatus"]=>string(21) "FORCE_CHANGE_PASSWORD" になっているので、パスワードを変更して、"CONFIRMED"に変える必要がある

パスワードを変更するには、CognitoIdentityProviderClient の adminSetUserPassword で行う。


<? php

~認証部分は同じなので、略~ 

try {
	$result = $client->adminSetUserPassword([
		'Password' => '新しいパスワード',
		'Permanent' => true,
	    'UserPoolId' => $userPoolId, 
	    'Username' => $email,
	]);
    
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    echo $e->getMessage() . "\n";
    error_log($e->getMessage());
}

?>

これで初回ログイン時のパスワード処理は完了し、getuserで確認すると、CONFIRMED になっている。

2.ログイン認証

ユーザーがログイン状態なのか調べるには、ログイン時に発行されるアクセストークンを手に入れる必要がある。上記のパスワード変更では、まだ発行されない。変更されたパスワードで正式にログインをすることで発行されるようだ。

ログインは、CognitoIdentityProviderClient の adminInitiateAuth で行う。また、アプリケーションクライアントのIDなどが必要となる、これはユーザープールの「アプリケーションの統合」タブの一番下にある作成したアプリケーションクライアントを選択すると記載がある。

このアプリケーションクライアント、PHP SDKでは、シークレットキーを使った認証時に必要なSRPキーの作成がちょっとわからなかったのでなしにした。なので、AuthFlowの値は、SRPを使用しない 'ADMIN_NO_SRP_AUTH' を指定して、usernameとpasswordを渡す。


<? php

~認証部分は同じなので、略~ 

try {
	
	$result = $client->adminInitiateAuth([
        'AuthFlow' => 'ADMIN_NO_SRP_AUTH',
        'AuthParameters' => [
            'Username' => $email,
            'PASSWORD' => 'パスワード'
        ],
        'ClientId' => 'clientIDを記入',
        'UserPoolId' => $userPoolId
    ]);
    
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    echo $e->getMessage() . "\n";
    error_log($e->getMessage());
}

?>

正常にログインできると、$resultの中にAccessTokenが発行されているのがわかるので、これをcookieなどに保存する。そして、このAccessTokenを使用して、getuserからユーザー情報を得ることができる


<? php

~認証部分は同じなので、略~ 

try {
    $client = new CognitoIdentityProviderClient($config);
    $result = $client->getUser([
    'AccessToken' => '保存したAccessToken', 
	]);

	$user_name = $result["UserAttributes"][2]["Value"];
	
}  catch (AwsException $e) {
    // output error message if fails
    echo $e->getMessage() . "\n";
    error_log($e->getMessage());
}

?>
<!doctype html>
<html lang="ja">
<body>
<p><?php echo $user_name; ?></p>
</body>
</html>

名前が表示されたので成功。ただ、UserAttributes の中はユーザープールの中身によって変わってくるので、一度 $result をvar_dump して中身をのぞいてみるといい。

また、cognitoの管理画面から、該当のユーザーの編集画面を出して、右上のアクションからサインアウトさせて再度確認すると、セッションが切れているため、エラーになるのがわかる。

3.キーの確認済み処理

ここまでの処理で一度Cognitoの管理画面でユーザープールをのぞくと、確認ステータスは確認済みになっているが、USERNAME(今回はE-mail)が確認済みになっていない。これは調べたところ、値を渡さないと直らないようなので、適切なタイミングで直す必要がある。

ユーザー情報のアップデートを行う必要があるので、CognitoIdentityProviderClient の adminUpdateUserAttributes で行う。UserAttributesに、email_verifiedを指定して、値を Trueにする。


<? php

~認証部分は同じなので、略~ 

try {	
	$result = $client->adminUpdateUserAttributes([
    'UserAttributes' => [
        [
            'Name' => 'email_verified',
            'Value' => 'True',
        ]
    ],
    'UserPoolId' => $userPoolId,
    'Username' => $email,
	]);
	
} catch (AwsException $e) {
    // output error message if fails
    echo $e->getMessage() . "\n";
    error_log($e->getMessage());
}

?>

これで管理画面をのぞくと確認済みの項目が、「いいえ」から「はい」になる。こういうのって初回パスワード発行時にユニークなログインURLを渡してアクセスがあったら変えるって感じでいいのかしらねぇ。。。まぁいいや。

次回は、トークンの更新や、サインアウト、パスワードを忘れたときの処理、usernameの変更などを調べたい。その次に2ファクターかな