Pages

2018年11月7日水曜日

[CakePHP3] オリジナルのログイン認証を作成

ちょっとややこしい要件が発生した。

ログインIDが1つでユニークではなく、店舗コード+社員コード という感じで2つのカラムでユニークとなる内容でした。

DBテーブルはこんな感じとする。

table: users
columns: id, shop_id, code, password

table: shops
columns: id, shop_id, code

そして、リクエスト値はこんな感じとする。

code, shop_code, password


やりたいSQLとしては

SELECT *
FROM users
INNER JOIN shops ON users.shop_id = shops.id
WHERE users.code = :code AND shops.code = :shop_code;

で取得してからパスワードチェックするというイメージ。

$this->loadComponent('Auth', [
    'loginAction' => [
        'controller' => 'Users',
        'action' => 'login',
    ],
    'authenticate' => [
        'Form' => [
            'userModel' => 'Users',
            'fields' => [
                'username' => 'username',
                'password' => 'password',
            ],
            'contain' => 'Shops', // 3.1 で非推奨
            'scope' => [], // 3.1 で非推奨
            'finder' => 'login',
        ],
    ],
    'authError' => 'ログインをして、ご利用ください。',
    'loginRedirect' => [
        'controller' => 'Users',
        'action' => 'index'
    ],
    'logoutRedirect' => [
        'controller' => 'Users',
        'action' => 'login'
    ]
]);

って感じでやりたいけど、shop_id を渡せない。。
scope や finder 使ってWHEREに固定した条件を追加する事はできるけど username を追加みたいな事ができない。。

で仕方ないので、オリジナルの Authenticate クラスを作成する事にする。

/src/Auth/UserAuthenticate.php

を作成。

中身は

getTableLocator()->get('Users');

        $user = $userTable->query()
            ->contain(['Shops'])
            ->where([
                'Users.code' => $request->getData('code', ''),
                'Shops.code' => $request->getData('shop_code', ''),
            ])
            ->first();

        $password = $request->getData('password', '');
        if ($this->passwordHasher()->check($password, $user->password)) {
            return $user->toArray();
        }

        return false;
    }
}

作成したら、

$this->loadComponent('Auth', [
    'loginAction' => [
        'controller' => 'Users',
        'action' => 'login',
    ],
    'authenticate' => [
        'Form' => [
            'userModel' => 'Users',
            'fields' => [
                'username' => 'username',
                'password' => 'password',
            ],
            'contain' => 'Shops', // 3.1 で非推奨
            'scope' => [], // 3.1 で非推奨
            'finder' => 'login',
        ],
    ],
    'authError' => 'ログインをして、ご利用ください。',
    'loginRedirect' => [
        'controller' => 'Users',
        'action' => 'index'
    ],
    'logoutRedirect' => [
        'controller' => 'Users',
        'action' => 'login'
    ]
]);

の記述を

$this->loadComponent('Auth', [
    'loginAction' => [
        'controller' => 'Users',
        'action' => 'login',
    ],
    'authenticate' => [
        'User' => [],
    ],
    'authError' => 'ログインをして、ご利用ください。',
    'loginRedirect' => [
        'controller' => 'Users',
        'action' => 'index'
    ],
    'logoutRedirect' => [
        'controller' => 'Users',
        'action' => 'login'
    ]
]);

と修正して完了。

0 件のコメント:

コメントを投稿

Followers