コンテンツに移動 ナビゲーションに移動

IT全般に関する雑記や技術ブログ。wordpressやPHP LaravelたまにPython

南の島のSE エンジニアブログ

Laravel
  1. HOME
  2. PHP
  3. Laravel
  4. Laravelで Amazon Cognito ログイン認証2【会員登録機能】
2022年9月2日 / 最終更新日 : 2022年9月2日 syun03 Laravel

Laravelで Amazon Cognito ログイン認証2【会員登録機能】

前回はLaravelをベースにAmazon Cognitoと連携したログイン認証を実装し、Cognito側の設定も行いました。

今回はLaravel側の会員登録ページからAmazon Cognitoへ会員登録する機能を実装します。

Laravel Cognito会員登録画面フロー

目次
  • 1. 会員登録時の検証タイプ変更
  • 2. 会員登録構築の流れ
  • 3. 会員登録画面のバリデーションチェック追加
  • 3.1. パスワードポリシーをCognitoに合わせる
  • 3.2. Cognitoの会員重複チェックを行う
  • 4. ControllerでCognito会員登録呼び出し
  • 5. Cognitoの会員登録API実行
  • 6. メールアドレス検証
  • 7. まとめ

会員登録時の検証タイプ変更

デフォルトではコードを入力させるタイプの設定になっています。

このままだとユーザ側の手間が少し増えますので、リンクタイプに変更しておきます。

設定はCognito管理コンソールの下記部分です。

全般設定->メッセージのカスタマイズ->Eメール検証メッセージカスタマイズ

Cognito Eメール検証の設定変更

会員登録構築の流れ

ログイン機能構築時と同様に、ベースはLaravel認証機能を利用します。

1会員登録画面のバリデーションチェック追加・パスワードポリシーをCognitoに合わせる
・Conigot側の会員重複チェックを行う
2RegisterControllerにCognitoAPIをコールする処理を追加・CognitoClientの準備
3Cognitoの会員登録APIを実行・会員登録処理時にsignUp APIを実行
4Laravel側の会員登録も実行・Cognito側の会員登録処理が成功したら、Laravelにも会員を作成

会員登録画面のバリデーションチェック追加

必要な作業は下記の2つになります。

  • パスワードポリシーをCognitoに合わせる
  • Cognito側の会員重複チェックを行う

パスワードポリシーをCognitoに合わせる

Cognitoのパスワードポリシーは下記の通りです。

Amazon Cognitoのパスワードポリシー

分かりづらいのですが、要約すると下記です。

  • 英数字を含む
  • 大文字と小文字をそれぞれ含む
  • 記号を含む

これを正規表現でパスワードの入力チェックに加えます。

    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8', 'confirmed',
                'regex:/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[\^$*.\[\]{}\(\)?\-\"!@#%&\/,><\':;|_~`])\S{8,99}$/'],
        ]);
    }

これでパスワードの入力チェックは完了です。

Cognitoの会員重複チェックを行う

LaravelとCognitoの会員状態は同期していることが利用ですが、何かの不具合で不整合が発生している可能性も考えられます。

Laravel側の会員重複チェックはメールアドレスをベースに実施されていますので、Cognito側も同じようにメールアドレスで重複チェックを行います。

まずはカスタムルールの準備

php artisan make:rule CognitoUserUnique

実装は下記の通りです。

<?php

namespace App\Rules;

use App\Cognito\CognitoClient;
use Aws\CognitoIdentityProvider\CognitoIdentityProviderClient;
use Illuminate\Contracts\Validation\Rule;

class CognitoUserUnique implements Rule
{
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    protected $config;
    public function __construct()
    {
        $this->config = [
            'region'      => config('cognito.region'),
            'version'     => config('cognito.version')
        ];
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {

        $client = new CognitoClient(
            new CognitoIdentityProviderClient($this->config)
        );

        $user = $client->getUserByUsername($value);
        if($user){
            return false;
        }
        return true;

    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'このメールアドレスはCognitoにすでに登録されています。';
    }
}

CognitoClientにgetUserByUsernameメソッドを作成し会員を取得します。

取得出来たら重複しているのでfalse(バリデーションNG)を返却し、取得できなければtrue(バリデーションOK)を返却します。

getUserByUsernameメソッドはあとで準備します。

ControllerでCognito会員登録呼び出し

RegisterControllerでは、バリデーションチェックが完了したらcreateメソッドが呼ばれ会員登録処理が実行されます。

ここにCognitoの会員登録APIを呼び出す処理を追加します。

    protected function create(array $data)
    {

        $config = [
            'region'      => config('cognito.region'),
            'version'     => config('cognito.version')
        ];
        $client = new CognitoClient(
            new CognitoIdentityProviderClient($config)
        );
        $client->createUser($data['email'],$data['password'],[]);


        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => '',

        ]);
    }

ここでもCognitoClinetを使って、createUserメソッドを呼び出しています。

createUserメソッドもあとで作成します。

Cognito側の会員登録が問題なく終われば、Laravel側のUser::create処理を実行しています。

Laravel側にはパスワードは不要になるので、空で登録するように変更しています。そのまま入れていても特に問題はございません。

Cognitoの会員登録API実行

CognitoClientに作成が必要なメソッドは2つになります。

  • createUser
  • getUserByUsername

前回作成したCognitoClientに機能を追加していきます。

    public function createUser($email,$password,$attributes){
        try
        {
            $response = $this->client->signUp([
                'ClientId' => $this->clientId,
                'Password' => $password,
                'SecretHash' => $this->getSecretHash($email),
                'UserAttributes' => $this->formatAttributes($attributes),
                'Username' => $email
            ]);

        } catch (CognitoIdentityProviderException $e) {
            if($e->getAwsErrorCode() === 'InvalidPasswordException'){
                throw new Exception('パスワードの形式が正しくありません。');
            }
            if($e->getAwsErrorCode() === 'UsernameExistsException'){
                throw new Exception('メールアドレスはすでに登録されています。');
            }
            throw $e;
        }
        return $response['UserSub'];
    }

    private function getSecretHash($username)
    {
        $hash = hash_hmac(
            'sha256',
            $username.$this->clientId,
            $this->client_secret,
            true
        );
        return base64_encode($hash);
}

    private function formatAttributes(array $attributes)
    {
        $userAttributes = [];
        foreach ($attributes as $key => $value) {
            $userAttributes[] = [
                'Name' => $key,
                'Value' => $value,
            ];
        }
        return $userAttributes;
    }

リファレンスに従いリクエストパラメータを設定します。SecretHashというハッシュ値も必須になっておりますので、SecretHash 値の計算を読んで実装します。

エラーが発生した場合はCognitoIdentityProviderExceptionが返却されます。

解説のために「InvalidPasswordException」と「UsernameExistsException」だけキャッチしてメッセージを記載しています。

他にも返却されるエラーコードはありますので、公式サイトの解説を確認しながら必要な処理を実装しましょう。

    public function getUserByUsername($username)
    {
        try {
            $user = $this->client->adminGetUser([
                'Username' => $username,
                'UserPoolId' => $this->poolId,
            ]);
        } catch (CognitoIdentityProviderException $e) {
            return false;
        }
        return $user;
    }

会員情報の取得にはadminGetUserというAPIを利用します。

メールアドレス検証

Laravelの会員登録画面を利用してもきちんとメールアドレス認証機能は実行されます。

メール宛に届いたリンクをクリックしないままだと、ログインすることはできません。

Cognito 未verify状態でのログイン

会員登録時に届いたメールのリンクをクリックするとログインできるようになります。

Cognito メールアドレス検証のメール
Cognito verify成功画面

メールアドレス検証画面も英語のままカスタマイズできないので、別画面にリダイレクトさせるなど対応が必要になりそうです。

まとめ

今回はLaravelを利用したCognito連携第2弾として会員登録機能を構築しました。

Laravel側にベースとなる機能が準備されているため、CognitoのAPIをコールする処理を加えるだけでほとんど実装は完了ですね。

Cognitoを使えばサイト間のSSOも簡単に実現することができます。

  • クリックして Twitter で共有 (新しいウィンドウで開きます)
  • Facebook で共有するにはクリックしてください (新しいウィンドウで開きます)

関連記事

LaravelとAmazon Cognitoでログイン実装
Laravelで Amazon Cognito ログイン認証1【ログイン機能】
 2022年8月31日
Laravel8でログイン機能実装5 会員情報更新
Laravel 8で会員サイト構築5 会員情報更新機能
 2020年9月19日
Laravel8でログイン機能実装4 値オプジェクト
Laravel8 ログイン機能実装4 値オブジェクトを用いたバリデーション
 2020年9月15日
Laravel8でログイン機能実装3
Laravel 8でログイン機能実装3 会員登録項目追加
 2020年8月31日
Laravel8でログイン機能実装2
Laravel 8でログイン機能実装2 ログインID導入
 2020年8月12日
Laravel8でログイン機能実装1
Laravel8でログイン機能実装1 基本機能導入編
 2020年8月7日
カテゴリー
Laravel
タグ
ログインcognito

コメントを残す コメントをキャンセル

Laravel
LaravelとAmazon Cognitoでログイン実装

前の記事

Laravelで Amazon Cognito ログイン認証1【ログイン機能】
2022年8月31日
AWS
AWS StorageGateway

次の記事

【AWS】Storage Gatewayの解説【概要】
2022年9月22日

検索

自己紹介

auther

南の島を愛するエンジニア
他にはない一歩踏み込んだ内容を心がけています。PHP/Phtyonでの開発やwordpressのカスタマイズ。最近はAWS
【IPA資格】
ITストラテジスト/ ITアーキテクト/ 情報セキュリティスペシャリスト

ココナラで活動中 お仕事のご依頼はこちら

【お友達紹介キャンペーン】ここから会員登録で1,000ポイント獲得

ランサーズはこちら お仕事承ります

人気記事

カテゴリー

  • AWS (5)
  • Python (4)
    • Django (4)
  • システム構築 (5)
  • PHP (19)
    • Laravel (18)
  • wordpress (31)
    • WooCommerce (5)
    • welcart (2)
  • ライフスタイル (1)
    • 副業 (1)
  • セキュリティ (1)
  • 資格 (35)
    • 基本情報技術者試験 (2)
    • プロジェクトマネージャ (7)
    • システムアーキテクト (3)
    • ITストラテジスト (5)
    • 情報処理安全確保支援士 (17)
  • その他 (7)

タグ

AWS (1) cognito (2) laravel-admin (4) SalonBookingSystem (5) simple-membership (3) stripe (5) subscription (1) wp-members (10) ドメイン駆動設計 (1) ログイン (6) 会員サイト (1)

目次

  • 1 会員登録時の検証タイプ変更
  • 2 会員登録構築の流れ
  • 3 会員登録画面のバリデーションチェック追加
    • 3.1 パスワードポリシーをCognitoに合わせる
    • 3.2 Cognitoの会員重複チェックを行う
  • 4 ControllerでCognito会員登録呼び出し
  • 5 Cognitoの会員登録API実行
  • 6 メールアドレス検証
  • 7 まとめ

当サイトについて

TOP |
プライバシーポリシー |
お問合せ

カテゴリー

  • AWS
  • Python
    • Django
  • システム構築
  • PHP
    • Laravel
  • wordpress
    • WooCommerce
    • welcart
  • ライフスタイル
    • 副業
  • セキュリティ
  • 資格
    • 基本情報技術者試験
    • プロジェクトマネージャ
    • システムアーキテクト
    • ITストラテジスト
    • 情報処理安全確保支援士
  • その他

タグ

  • laravel
  • wp-members
  • 会員サイト
  • ドメイン駆動設計
  • simple-membership
  • stripe
  • SalonBookingSystem
  • laravel-admin
  • subscription
  • AWS
  • ログイン
  • cognito

最近の投稿

プロジェクトマネージャ試験令和4年度秋季 午後1問3解答速報
【解答・解説】プロジェクトマネージャ 令和4年度秋季【午後1問3】
2022年10月15日
プロジェクトマネージャ試験令和4年度秋季 午後1解答速報
【解答・解説】プロジェクトマネージャ 令和4年度秋季【午後1問2】
2022年10月12日
【解答・解説】情報処理安全確保支援士 令和4年度秋季【午後2問2】
2022年10月10日
情報処理安全確保支援士令和4年度秋季 午後1解答速報
【解答・解説】情報処理安全確保支援士 令和4年度秋季【午後1問3】
2022年10月9日
情報処理安全確保支援士令和4年度秋季 午後1解答速報
【解答・解説】情報処理安全確保支援士 令和4年度秋季【午後1問2】
2022年10月9日

Copyright © 南の島のSE エンジニアブログ All Rights Reserved.

MENU
  • HOME