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

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

ただいまの
回答率

90.75%

  • CakePHP

    2214questions

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

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

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 128

funchoic

score 3

 前提・実現したいこと

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()でもユーザー情報が取得できました。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

check解決した方法

0

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/08 16:11

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

    キャンセル

  • 2018/06/08 16: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
    ----------------------------------------
    ※ログイン時は何も追記されませんでした。

    もし、的外れな事をしていたらすみません。お手数をお掛けいたしますがよろしくお願いいたします。

    キャンセル

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 17:55

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

    また、結果報告させて頂きます。

    キャンセル

  • 2018/06/08 23:50

    認識が間違っていたらすみません。下記の箇所ですが、

    >Security::decrypt($request->getData($fields['username']),$key),

    Security::encrypt($request->getData($fields['username']),$key),では無いでしょうか?

    DBには暗号化されて入っているので、平文で入力されたuseridを暗号化して検索する?という感じになるのかな?とおもっているのですが。。

    ちなみに、Security::decrypt($request->getData($fields['username']),$key)は空でした。

    キャンセル

  • 2018/06/09 00:16

    上記の補足になりますが、

    $request->getData($fields['username'])には、ログインフォームで入力したuseridが平文で入っていました。また、$keyにもDBに保存した時(暗号化した時)と同じ値が入っていました。

    ちなみにSecurity::encrypt($request->getData($fields['username']),$key)でやると、暗号化されたデータが存在するのですが、、何だかログインを試みる度に値が異なっているような。。もう少し色々調べて見ます。

    キャンセル

  • 2018/06/10 21:46

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

    キャンセル

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

  • ただいまの回答率 90.75%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • CakePHP

    2214questions

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

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