cake version | 3.3.11 |
---|
ここに絶対やるなよ!って書いてありますが、どうしてもやりたい人のために記載しておきます。
https://book.cakephp.org/3.0/ja/core-libraries/security.html
ハッシュでの比較をしない(絶対やるなよ!)パスワードハッシャを作成。
src/Auth/NonPasswordHasher.php
<?php
namespace App\Auth;
use Cake\Auth\AbstractPasswordHasher;
class NonPasswordHasher extends AbstractPasswordHasher
{
public function hash($password)
{
return $password;
}
public function check($password, $hashedPassword)
{
return $password === $hashedPassword;
}
}
ユーザマスタのEntityにパスワード暗号・復号化のSetterとGetterを書く。
※Usersテーブルのpasswordフィールドは、大きめのvarcharかtextで。
src/Model/Entity/User.php
<?php
use Cake\Utility\Security;
..
class User extends Entity{
private $passwordKey = '33 Keta Ijou No Mojiretu Wo Iretene';
//configに宣言してもOK。ほんとはレコード毎に用意しなくちゃ偉い人に怒られます!
....
protected function _getPassword($value)
{
if ($value) {
//↓これ大切!!
return $this->dirty('password') ?
$value :
Security::decrypt(hex2bin($value), $this->passwordKey);
}
}
protected function _setPassword($value)
{
if ($value) {
return bin2hex(Security::encrypt($value, $this->passwordKey))
}
}
}
APPコントローラに認証設定
src/Controller/AppController.php
class AppController extends Controller
{
public function initialize() {
$this->loadComponent('Auth', [
'loginAction' => [
'controller' => 'Users',
'action' => 'login'
],
'loginRedirect' => [
'controller' => 'Users',
'action' => 'index'
],
'authenticate' => [
'Form' => [
'userModel' => 'Users',
'fields' => [
'username' => 'username',
'password' => 'password'
],
'passwordHasher' => [
'className' => 'Non',//NonPasswordHasherを指定
]
]
]
]);
$this->Auth->sessionKey = 'Auth.User';
$this->Auth->allow(['login','logout']);
}
}
ご注意!!
テーブル挿入・更新時などsetterが呼ばれた後にまさかgetterが呼ばれているとは気づかず、生パスでDB登録されることがわかりましたorz
とりあえずgetterでdirty判定をつけてやれば、登録できましたが、本当にこんなんでいいのか分からないです。
たとえばテーブル挿入・更新時にserializeして、取り出す時はunserializeする時とか正しい方法はどうやるんでしょうね。
詳しい方教えてください。
class UsersController extends AppController
...
public function edit($id = null)
{
$user = $this->Users->get($id);
$user = $this->Users->patchEntity($users, $this->request->data);
//↑ここでは、ちゃんとUser::_setPasswordが呼ばれて暗号化されてる
if(!$user->errors()) {
if ($this->Users->save($user)) {
//↑ここで$entity->extractからのUser::_getPasswordが呼ばれて復号化されてupdate実行..orz
...
}
}
}
}