今回は認証をまとめる
前回四苦八苦しながら作成したプールに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ファクターかな