質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Q&A

解決済

3回答

1910閲覧

CakePHP3のAuthComponentのusernameキー値を暗号化していると認証に失敗してしまいます。(平文だとうまくいきます)

funchoic

総合スコア11

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

0グッド

0クリップ

投稿2018/06/08 06:28

前提・実現したいこと

CakePHP3.5.16でAuthComponentで認証機能を付けようとしています。その際、passwordキーはdefaultのpassordHasherを使用し、usernameキーはSecurity::encryptで暗号化した物を使用したいと考えています。

実際にログインフォームより、usernameキー値とpasswordキー値を入力して送信すると、$this->Auth->identify()でfalseが戻り、認証に失敗してしまいます。

該当のソースコード

AppController.php

$this->loadComponent('Auth', [ 'authorize' => ['Controller'], 'storage' => 'Session', 'authenticate' => [ 'Form' => [ 'fields' => [ 'username' => 'userid',//usernameキーにはuseridフィールドを使用しています。 'password' => 'password' ], 'userModel' => 'Members', ], ],          //(リダイレクト関連一部省略) ]);

Member.php

public function _defaultEncrypt($value) { return Security::encrypt(trim($value), $this->defaultKey); } public function _defaultDecrypt($name, $value) { return $this->dirty($name) ? $value : Security::decrypt(trim($value), $this->defaultKey); } /* * 会員IDの暗号化 * */ protected function _setUserid($value) { if ($value) return $this->_defaultEncrypt($value); } protected function _getUserid($value) { if ($value) return $this->_defaultDecrypt('userid', $value); } /* * パスワードのハッシュ化 * */ protected function _setPassword($value) { $hasher = new DefaultPasswordHasher(); return $hasher->hash($value); }

MembersController.php

/* * 会員アカウントのログイン **/ public function login() { //ログイン済み if($this->_loginSt) return $this->redirect(['action'=>'home']); $member = $this->Members->newEntity(); if($this->request->is(['post','put'])) { $identify = $this->Auth->identify(); if ($identify) { $this->Auth->setUser($identify); } else { $this->set(compact('member')); $this->Flash->error('入力値が間違っているか、メールアドレスの認証をされていない可能性があり>ます'); } }

試したこと

  1. DBのpasswordフィールドとuseridフィールドに値が入っている事を確認 ⇒ 入っていました。
  2. useridを平文に変更(Members.phpで実行している暗号化をコメントアウト) ⇒ DBに平文でuseridが入り、identify()でもユーザー情報が取得できました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

_getXXX _setXXX はDBから値を取り出す時/保存する時に変換されます。

useridカラムを暗号化しているのならフォームから入力した後の値を変換してあげてその値を使ってDBから検索する必要があります。

FormAuthenticateを基底クラスとした新カスタム認証を作って
https://book.cakephp.org/3.0/ja/controllers/components/authentication.html#id12

ここの部分をオーバーライドすると良いと思います
https://github.com/cakephp/cakephp/blob/de7ebdb88e11c4283185ba33c827151f02352b4b/src/Auth/FormAuthenticate.php#L76-L79

return $this->_findUser( Security::encrypt($request->getData($fields['username']),$key), $request->getData($fields['password']) );

のような感じでしょうか...

またはリクエストデータをコントローラで identify() を実行する前に$request->data の中身を変えるかですね..

投稿2018/06/08 08:47

編集2018/06/11 02:31
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

funchoic

2018/06/08 08:55

回答ありがとうございます。勉強になるので両方とも試させて頂きます。本当にありがとうございます。助かります。 また、結果報告させて頂きます。
funchoic

2018/06/08 14:50

認識が間違っていたらすみません。下記の箇所ですが、 >Security::decrypt($request->getData($fields['username']),$key), Security::encrypt($request->getData($fields['username']),$key),では無いでしょうか? DBには暗号化されて入っているので、平文で入力されたuseridを暗号化して検索する?という感じになるのかな?とおもっているのですが。。 ちなみに、Security::decrypt($request->getData($fields['username']),$key)は空でした。
funchoic

2018/06/08 15:16

上記の補足になりますが、 $request->getData($fields['username'])には、ログインフォームで入力したuseridが平文で入っていました。また、$keyにもDBに保存した時(暗号化した時)と同じ値が入っていました。 ちなみにSecurity::encrypt($request->getData($fields['username']),$key)でやると、暗号化されたデータが存在するのですが、、何だかログインを試みる度に値が異なっているような。。もう少し色々調べて見ます。
funchoic

2018/06/10 12:46

いろいろと試みましたが、無理そうなので、平文で保存する事にします。ご対応ありがとうございました。
nojimage

2020/10/26 13:09 編集

今更ですが捕捉です。CakePHP 3以降のSecurity::encryptはCBCモードで暗号化されており、encryptを実行するたびに違った値となります。このため。上記findUserの修正だけでは足りず、暗号化エンジンを変更してIV(初期化ベクトル)を固定するかEBCモードで暗号化する必要があります。ただし、IVを固定したりEBCにすると脆弱になりますのでこれらに変更することは推奨できません。
guest

0

自己解決

今の自分の力では解決できないので、平文でデータを保存するように”仕様変更”で対応しました。

(※teratailからベストアンサーを選べとの催促が来たのですが、解決は出来なかったので、とりあえずこの欄に記入して終了とさせて頂きます。)

投稿2018/06/11 03:06

funchoic

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

_setXxxxx のメソッドにログ出力を追記してみてはいかがでしょうか?

比較対象がハッシュ化された情報二重にハッシュ化された情報の比較になってるはずです

投稿2018/06/08 06:49

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

funchoic

2018/06/08 07:11

回答ありがとうございます。試してみます。
funchoic

2018/06/08 07:52

時間が掛かってすみません。勉強の意味も有るので、自分でログの出力方法をマニュアル見ながらやって見たのですが。検討違いな事をしていたらすみません。 -------以下変更箇所(Member.php)------- use Cake\Log\Log;//追記 protected function _setUserid($value) { Log::write('debug', $value); //追記 if ($value) return $this->_defaultEncrypt($value); } protected function _setPassword($value) { Log::write('debug', $value); //追記 $hasher = new DefaultPasswordHasher(); return $hasher->hash($value); } ----------------------------------- ----log/debug.phpの中身(アカウント作成時)---- 2018-06-08 16:32:33 Debug: testid 2018-06-08 16:32:33 Debug: testpassword ---------------------------------------- ※ログイン時は何も追記されませんでした。 もし、的外れな事をしていたらすみません。お手数をお掛けいたしますがよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問