CakePHP 2.4 md5 で Auth認証

## 概要

PHP 5.4
CakePHP Version 2.4.2

Auth コンポーネントをデフォルトでそのまま使うと、パスワードがソルト付きの sha1() で暗号化されてテーブルの値と比較される。
この暗号化処理を自分で自由に変更したい。

## コアの動き

```php
class SimplePasswordHasher
  // ここでハッシュ化されている
  public function hash($password) {
    return Security::hash($password, $this->_config['hashType'], true);
  }
```

```php
class Security {
  public static function hash($string, $type = null, $salt = false) {
    // デフォルトだと、ソルトを文字列の先頭につけて sha1() で返す
    $salt = Configure::read('Security.salt');
    $string = $salt . $string;
    return sha1($string);
```

## 注意

パスワードは md5 などで暗号化するだけでなく、ソルト付きの値をつけてハッシュ化する方がセキュリティ的に望ましいそうです。既存の案件ですでにパスワード形式が固定化されている場合や、独自の暗号化方式が使われている場合にご参考ください。

## 作成したソース

```php:App/Controller/UsersController.php
<?php

App::uses('AppController', 'Controller');
App::uses('FormHashAuthenticate', 'Controller/Component/Auth');
App::uses('Md5PasswordHasher', 'Controller/Component/Auth');

class UsersController extends AppController {
	public $components = [
		'Auth' => [
			'authError' => 'ＩＤかパスワードが間違っています。',
			'loginRedirect'  => [
				'controller' => 'menus',
				'action' => 'index'
			],
			'authenticate' => [
				'FormHash' => [
					'userModel' => 'User',
					'passwordHasher' => [
						'className' => 'Md5',
	                ],
				]
			],
		],
	];
	public function login() {
		if ($this->request->is('post')) {
			if ($this->Auth->login()) {
				return $this->redirect($this->Auth->redirectUrl());
			} else {
				$this->Session->setFlash($this->Auth->authError,
					'default', array(), 'auth');
			}
		}
	}
}
```

```php:App/Controller/Component/Auth/FormHashAuthenticate.php
<?php

App::uses('FormAuthenticate', 'Controller/Component/Auth');

class FormHashAuthenticate extends FormAuthenticate {
	public function getUser(CakeRequest $request) {
		$userModel = $this->settings['userModel'];
		$field_username = $this->settings['fields']['username'];
		$field_password = $this->settings['fields']['password'];
		if (isset($request->data[$userModel]) &&
			!empty($request->data[$userModel][$field_username]) &&
			!empty($request->data[$userModel][$field_password])) {
			$username = $request->data[$userModel][$field_username];
			$password = $request->data[$userModel][$field_password];
			return $this->_findUser($username, $password);
		}
		return false;
	}
}
```

```php:App/Controller/Component/Auth/Md5PasswordHasher.php
<?php

App::uses('AbstractPasswordHasher', 'Controller/Component/Auth');

class Md5PasswordHasher extends AbstractPasswordHasher {
	public function hash($password) {
		return md5($password);
	}
	public function check($password, $hashedPassword) {
		return $hashedPassword === $this->hash($password);
	}
}
```

```php:App/View/Users/login.ctp
<?= $this->Form->create('User', array('url' => '/users/login')); ?>
・ＩＤ<br>
<?= $this->Form->input('User.username',
	array('label' => false, 'type' => 'text')); ?><br>
・パスワード<br>
<?= $this->Form->input('User.password',
	array('label' => false, 'type' => 'password')); ?><br>
<? $error = $this->Session->flash('auth'); ?>
<? echo (!empty($error)) ? $error : ''; ?>
<?= $this->Form->end('ログイン'); ?><br>
```

```php:App/Model/User.php
<?php

App::uses('AppModel', 'Model');

class User extends AppModel {
	public $name = 'User';
}
```