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

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

ただいまの
回答率

90.84%

  • PHP

    18214questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • CakePHP

    2168questions

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

  • Authentication

    65questions

    Authentication(認証)は正当性を認証する為の工程です。ログイン処理等で使われます。

CakePHP3.5 パスワードで"0"ゼロを入力すると認証しない

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 181

gekota

score 2

Cakephp3.5でパスワードが"0"と設定しているユーザだけ、認証が通りません。
認証はMD5でハッシュ化済みのパスワードを照合する様にしています。
※"0"のMD5ハッシュ値: cfcd208495d565ef66e7dff9f98764da でDBに登録済み
ゼロだから数値として認識しているかと思い、LegacyPasswordHasher.phpの$passwordをstrval関数やキャスト演算子(string)などで文字列化してみましたが全く改善しませんでした。

0の場合だけ、LegacyPasswordHasher.php が動作していないみたいです。
DebugKitのRequestを確認するとユーザー名とパスワード(0)は問題無くPOST出来ています。

なお、[tbUserAuths]テーブルには、ユーザ名とパスワード(MD5でハッシュ化済み)したデータがあります。
どこを修正すれば認証するのかご教授お願い致します。

\src\Controller\AppController.php

<?php
namespace App\Controller;
use Cake\Controller\Controller;
use Cake\Event\Event;

class AppController extends Controller
{
    public function initialize()
    {
        parent::initialize();

        $this->loadComponent('RequestHandler');
        $this->loadComponent('Flash');
        $this->loadComponent('Security');
        $this->loadComponent('Csrf');
        $this->loadComponent('Auth', [
            'authorize'             => [ 'Controller'],
            'authenticate'          => [ 'Form' => ['fields'         => ['username' => 'username', 'password' => 'password' ] ,
                                                    'userModel'      => 'tbUserAuths',
                                                    'passwordHasher' => ['className' => 'Legacy'] ] ],
            'unauthorizedRedirect'  => [ 'controller' => 'Users' , 'action' => 'login' ],
            'loginRedirect'         => [ 'controller' => 'Homes' , 'action' => 'index' ],
            'logoutRedirect'        => [ 'controller' => 'Users' , 'action' => 'login' ],
            'loginAction'           => '/users/login',
            'authError'             => false
        ]);
    }

    public function beforeRender(Event $event)
    {
        if (!array_key_exists('_serialize', $this->viewVars) &&
            in_array($this->response->type(), ['application/json', 'application/xml'])
        ) {
            $this->set('_serialize', true);
        }
    }

    public function isAuthorized($user)
    {
        // Admin can access every action
        if (isset($user['role_name']) && $user['role_name'] === 'admin') {
            return true;
        }
        // Default deny
        return false;
    }
}
\src\Auth\LegacyPasswordHasher.php

<?php
namespace App\Auth;
use Cake\Auth\AbstractPasswordHasher;

class LegacyPasswordHasher extends AbstractPasswordHasher
{
    public function hash($password)
    {
        return md5($password);
    }

    public function check($password, $hashedPassword)
    {
        return md5($password) === $hashedPassword;
    }
}
\src\Model\Entity\User.php

<?php
namespace App\Model\Entity;
use Cake\Auth\DefaultPasswordHasher;
use Cake\ORM\Entity;

class User extends Entity
{
    protected $_accessible = [
        '*' => true,
    ];
    protected $_hidden = [
        'password'
    ];

    protected function _setPassword($password)
    {
        if (strlen($password) > 0) {
            return (new DefaultPasswordHasher)->hash($password);
        }
    }
}
\src\Controller\UsersController.php

<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\Event;
use Cake\Datasource\ConnectionManager;

class UsersController extends AppController
{
    public function initialize()
    {
        parent::initialize();
    }

    public function login()
    {
        if ($this->request->is('post')) {

            $user = $this->Auth->identify();

            if ($user) {
                $this->Auth->setUser($user);
                $session = $this->request->session();
                if ($this->Auth->user()) {
                      $session->write('Member', $query);
                      $session->write('Auth.User.role', $query['role_name']);
                      return $this->redirect([ 'controller' => 'Homes' , 'action' => 'index' ]);      
                }
            }
            $this->Flash->error(__('パスワードが違います。'));
        }
    }

    public function logout()
    {
        return $this->redirect($this->Auth->logout());
    }


    public function beforeFilter(Event $event)
    {
        parent::beforeFilter($event);
        $this->Auth->allow(['logout']);
    }

   public function isAuthorized($user)
    {
        return true;
    }
}

ユーザーのテーブル構成を追加

CREATE TABLE `tb_user_auths` (
    `username` CHAR(6) NOT NULL,
    `password` VARCHAR(255) NULL DEFAULT NULL,
    PRIMARY KEY (`username`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;


ちなみにCakePHPからパスワード設定は行いません。
既にDBへ登録済みのMD5でハッシュ化されたパスワードを参照します。
例えば、以下の内容で入力した場合、

ユーザー名:012345
パスワード:1

ユーザーテーブルに以下の内容がヒットすればログインします。

usernemae:012345
password:c4ca4238a0b923820dcc509a6f75849b

今回の場合は、ゼロの場合だけログイン出来ません。
その際のテーブルにあるデータは以下になります。
password:cfcd208495d565ef66e7dff9f98764da

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • mts10806

    2018/04/13 14:02 編集

    0はboolean的にfalseだからかな・・とふと思いましたが、CakePHP環境なくて確証とれていないので回答には至れていません。そもそもパスワード0だけで認証ってどうなんだろう?という疑問があります。

    キャンセル

  • asahina1979

    2018/04/13 20:07

    登録用と認証用ハッシャーがちがうのな(笑)

    キャンセル

  • asahina1979

    2018/04/13 23:11

    とりま ユーザーテーブルの構成がわからんと回答のしようがないな

    キャンセル

回答 2

checkベストアンサー

+4

試してないからわからんけどたぶんここ。

https://github.com/cakephp/cakephp/blob/3.5.15/src/Auth/FormAuthenticate.php

    if (empty($value) || !is_string($value)) {
        return false;
    }

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/04/16 21:13

    empty("0")== true まじだww

    キャンセル

  • 2018/04/17 12:47 編集

    rana_kualuさんの内容で改善しました!

    /vendor/cakephp/cakephp/src/Auth/FormAuthenticate.php
    ↓コピー
    /src/Auth/FormAuthenticate.php

    上記ファイルを下記の様に修正しました。

    protected function _checkFields(ServerRequest $request, array $fields)
    {
    foreach ([$fields['username'], $fields['password']] as $field) {
    $value = $request->getData($field);
    // パスワード[0] のユーザー対応
    if ($value == 0) {
    return true;
    }
    if (empty($value) || !is_string($value)) {
    return false;
    }
    }
    return true;
    }

    キャンセル

  • 2018/04/17 12:50

    質問者、そのファイル修正するといつの間にか消えるよ

    キャンセル

0

はじめまして

    public function hash($password)
    {
        return md5($password);
    }


このmd5関数と

    public function check($password, $hashedPassword)
    {
        return md5($password) === $hashedPassword;
    }


こちらのmd5関数ですが

1 同じmd5関数を使っているのでしょうか? PHP7の標準関数md5でしょうか?
※同一だと思うのですが・・・

もし同じであるとして
md5関数の定義、ソースは
どういったロジックになっていますか?

2 まさかと思うのですが、check($password, $hashedPassword)の引数$passwordが
’0’ではなく
別の値が入っていることはないでしょうか。

一応

ゼロだから数値として認識しているかと思い、LegacyPasswordHasher.phpの$passwordをstrval関数やキャスト演算子(string)などで文字列化してみましたが全く改善しませんでした。

で確認されているかと思いますが。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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

  • PHP

    18214questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • CakePHP

    2168questions

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

  • Authentication

    65questions

    Authentication(認証)は正当性を認証する為の工程です。ログイン処理等で使われます。