CakePHPの認証でアカウントロックを実装してみる
はじめに
アカウントロックって実装したことないなと思ったので
CakePHPで実装してみます。
前提
エラー回数10で認証できないようにする
- usersテーブルにエラー回数を追加
CREATE TABLE users ( id bigserial NOT NULL, username character varying(64), password character varying(256), role character varying(32), creaated timestamp with time zone, modified timestamp with time zone, error_count integer NOT NULL, CONSTRAINT users_pkey PRIMARY KEY (id) );
- error_countが10以上ならロックされましたエラーにする
AppController.phpでauthenticateの検索条件にerror_countが10未満を追加します。
public $components = array( 'Session', 'Auth' => array( 'loginRedirect' => array('controller' => 'books', 'action' => 'index'), 'logoutRedirect' => array('controller' => 'pages', 'action' => 'display', 'home'), 'authenticate' => array( 'Form' => array( 'passwordHasher' => 'Slow', 'scope' => array( 'User.error_count <' => 10) ) ) ) );
- アカウントロックだとわかるようにUsersController.phpのlogin()を修正する。
UsersController.phpのlogin()抜粋
public function login() { if ($this->request->is('post')) { if ($this->Auth->login()) { $this->redirect($this->Auth->redirect()); } else { $options = array('conditions' => array('User.username' => $this->request->data['User']['username'], 'User.error_count >=' => 10)); $lockedUser = $this->User->find('first', $options); if (!empty($lockedUser)) { $this->Session->setFlash(__('Account is locked.')); } else { $this->Session->setFlash(__('Invalid username or password, try again')); } } } }
User.phpにincrementErrorCount()を追加
public function incrementErrorCount($target) { $data = array('id' => $target['id'], 'error_count' => $target['error_count'] + 1); $fields = array('error_count'); $this->save($data, false, $fields); }
UsersController.phpのlogin()抜粋
public function login() { if ($this->request->is('post')) { if ($this->Auth->login()) { $this->redirect($this->Auth->redirect()); } else { $options = array('conditions' => array('User.username' => $this->request->data['User']['username'])); $lockedUser = $this->User->find('first', $options); if (!empty($lockedUser) && $lockedUser['User']['error_count'] >= 10) { $this->Session->setFlash(__('Account is locked.')); } else { if (!empty($lockedUser)) { $this->User->incrementErrorCount($lockedUser['User']); } $this->Session->setFlash(__('Invalid username or password, try again')); } } } }
まとめ
これで10回続けてエラーの場合アカウントがロックされるようになりました。
「ロック解除は管理者に連絡してください」って運用じゃだめですよね。
一定時間たったらアカウントロック解除しないといけないですね。
気が向いたらやってみます。