Help us understand the problem. What is going on with this article?

AWS Cognito ✗ Laravelを使った会員機能構築の話

はじめに

ここ3ヶ月程、某WEBサイトに会員機能+決済機能を追加するお仕事をしてました。
基本的に設計〜リリースまで自分主担当で進めるにあたり、なんか便利な外部サービスないかなと目をつけたのがAWS Coginitoでした。

導入対象のシステム構成

インフラはAWSを使っており、サーバーサイド&フロントはphp×Laravel構成です。

導入の背景

リリースまで3ヶ月、運用を楽にしたい、個人情報周りを自社で持つようなことをしたくないというのを軸にいい感じのサービスないかなーと探しておりました。
AWSでいい感じのマネージドサービスあるんじゃないかと思って見つけたCognito。さっとドキュメント読んだ感じ、ソーシャルIDプロバイダーを介したサインインや多要素認証(MFA)といった機能もあり導入を決めました。

検証・設計時に苦労したこと

cognitoで検索すると結構な数の記事が出てきたのですが、どれもAWS Amplifyを使ったモダンな利用方法ばかり。。。自分のようにサーバーサイドで使う例があまり見当たらず、また公式ドキュメントもamplifyを使った例しか見つけれず中々時間がかかりましたが、
aws-sdk-phpのCognitoIdentityProviderClientを利用すればできそうなところまでなんとかあたりをつけられました。

Cognito側の設定

まずはマネジメントコンソールからUserPoolsを作成します。
で出来上がったのがこちら。
スクリーンショット 2019-11-30 14.19.55.png
スクリーンショット 2019-11-30 14.26.04.png

CognitoIdentityProviderClientのAPI呼び出しにおいて、プールID(UserPoolId)およびアプリクライアントID(ClientId)を指定しなければならないものもあるため確認しておきます。
また、トークンの有効期限を更新(日)の項目もAPI呼び出しに必要なTokenの有効期限を設定するもののため適切な値に適宜設定すると良いと思います。

サーバーサイドからのCognitoAPI呼び出し

私が主に使用したのは認証・取得・更新のAPIになります。
それぞれ下記のような形で呼び出せます。

sample.php
$email = $request->input('email');
$password = $request->input('password');

$client = new CognitoIdentityProviderClient([
            'profile' => 'default',
            'region'  => 'ap-northeast-1', // 東京リージョンの場合
            'version' => '2016-04-18'
        ]);
$result = $client->initiateAuth([
    'AuthFlow' => 'USER_PASSWORD_AUTH',
    'ClientId' => 'アプリクライアントID',
    'AuthParameters' => ['USERNAME' => $email, 'PASSWORD' => $password],
]);

レスポンスはこんな感じです。

[
    'AuthenticationResult' => [
        'AccessToken' => '<string>',
        'ExpiresIn' => <integer>,
        'IdToken' => '<string>',
        'NewDeviceMetadata' => [
            'DeviceGroupKey' => '<string>',
            'DeviceKey' => '<string>',
        ],
        'RefreshToken' => '<string>',
        'TokenType' => '<string>',
    ],
    'ChallengeName' => 'SMS_MFA|SOFTWARE_TOKEN_MFA|SELECT_MFA_TYPE|MFA_SETUP|PASSWORD_VERIFIER|CUSTOM_CHALLENGE|DEVICE_SRP_AUTH|DEVICE_PASSWORD_VERIFIER|ADMIN_NO_SRP_AUTH|NEW_PASSWORD_REQUIRED',
    'ChallengeParameters' => ['<string>', ...],
    'Session' => '<string>',
]

この中で重要なのがAccessTokenとRefreshTokenになります。
AccessTokenは認証後にユーザー情報の取得や更新等他のAPIを呼び出す際にKeyとして利用します。ただし、有効期限は発行から1hです。
次にRefreshTokenですが、AccessTokenおよびIdToken(今回は利用していない)の再発行に利用するためのTokenです。
こちらの有効期限は前述の トークンの有効期限を更新(日)で設定した期間になります。
ちなみに取得したtoken達はLaravelのsessionで保管をしています。

AccessTokenを使ってユーザー情報を取得するのはこんな感じになります。

getuser.php
$accesstoken = session('access_token');
$result = $client->getUser([
    'AccessToken' => $accesstoken,
]);

まとめ

自身が調査しているときは情報が中々出てこなくて多少時間がかかりましたが、この記事を書いてる時点でととても詳しく書かれているサーバーサイド✕Cognitoの記事もいくつか見つけられました。
システム構成上しかたなくでしたが、スクラッチで作るのであればやはりamplifyの方がもっと便利で簡単にできるかもしれません。
ある程度出来上がってしまっているシステムに対してCognitoを導入する際の参考に少しでもなれれば幸いです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away