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

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

ただいまの
回答率

89.52%

cakephp ログインがうまくいかない

解決済

回答 1

投稿 編集

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

tunnel

score 20

ログインがうまくいかないので色々見ていたらハッシュ化ができていないことに気づきました。
しかし命名規則も守れているようだし原因がわかりません。お力添えをお願いします。

<?php
namespace App\Model\Entity;

use Cake\ORM\Entity;
use Cake\Auth\DefaultPasswordHasher;

/**
 * User Entity
 *
 * @property int $id
 * @property string $username
 * @property string $password
 * @property string $role
 *
 * @property \App\Model\Entity\Bidinfo[] $bidinfo
 * @property \App\Model\Entity\Biditem[] $biditems
 * @property \App\Model\Entity\Bidmessage[] $bidmessages
 */
class User extends Entity
{
    /**
     * Fields that can be mass assigned using newEntity() or patchEntity().
     *
     * Note that when '*' is set to true, this allows all unspecified fields to
     * be mass assigned. For security purposes, it is advised to set '*' to false
     * (or remove it), and explicitly make individual fields accessible as needed.
     *
     * @var array
     */
    protected $_accessible = [
        'username' => true,
        'password' => true,
        'role' => true,
        'bidinfo' => true,
        'biditems' => true,
        'bidmessages' => true
    ];

    /**
     * Fields that are excluded from JSON versions of the entity.
     *
     * @var array
     */
    protected $_hidden = [
        'password'
    ];

    protected function _setPassword($password) {
      return (new DefaultPasswordHasher)->hash($password);
    }
}
//UserController.php
<?php
namespace App\Controller;

use App\Controller\AppController;
use Cake\Auth\DefaultPasswordHasher;
use Cake\Event\Event;

/**
 * Users Controller
 *
 * @property \App\Model\Table\UsersTable $Users
 *
 * @method \App\Model\Entity\User[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
 */

class UsersController extends AppController
{
    /**
     * Index method
     *
     * @return \Cake\Http\Response|null
     */
    public function index()
    {
        $users = $this->paginate($this->Users);

        $this->set(compact('users'));
    }

    /**
     * View method
     *
     * @param string|null $id User id.
     * @return \Cake\Http\Response|null
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function view($id = null)
    {
        $user = $this->Users->get($id, [
            'contain' => ['Bidinfo', 'Biditems', 'Bidmessages']
        ]);

        $this->set('user', $user);
    }

    /**
     * Add method
     *
     * @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
     */
    public function add()
    {
        $user = $this->Users->newEntity();
        if ($this->request->is('post')) {
            $user = $this->Users->patchEntity($user, $this->request->getData());
            if ($this->Users->save($user)) {
                $this->Flash->success(__('The user has been saved.'));

                return $this->redirect(['action' => 'index']);
            }
            $this->Flash->error(__('The user could not be saved. Please, try again.'));
        }
        $this->set(compact('user'));
    }

    /**
     * Edit method
     *
     * @param string|null $id User id.
     * @return \Cake\Http\Response|null Redirects on successful edit, renders view otherwise.
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function edit($id = null)
    {
        $user = $this->Users->get($id, [
            'contain' => []
        ]);
        if ($this->request->is(['patch', 'post', 'put'])) {
            $user = $this->Users->patchEntity($user, $this->request->getData());
            if ($this->Users->save($user)) {
                $this->Flash->success(__('The user has been saved.'));

                return $this->redirect(['action' => 'index']);
            }
            $this->Flash->error(__('The user could not be saved. Please, try again.'));
        }
        $this->set(compact('user'));
    }

    /**
     * Delete method
     *
     * @param string|null $id User id.
     * @return \Cake\Http\Response|null Redirects to index.
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function delete($id = null)
    {
        $this->request->allowMethod(['post', 'delete']);
        $user = $this->Users->get($id);
        if ($this->Users->delete($user)) {
            $this->Flash->success(__('The user has been deleted.'));
        } else {
            $this->Flash->error(__('The user could not be deleted. Please, try again.'));
        }
        return $this->redirect(['action' => 'index']);
    }

    public function initialize()
    {
      parent::initialize();
      //各種コンポーネントのロード
      $this->loadComponent('RequestHandler');
      $this->loadComponent('Flash');
      $this->loadComponent('Auth', [
        'authorize'=>['Controller'],
        'authenticate'=>[
          'Form'=>[
            'fields'=>[
              'username'=>'username',
              'password'=>'password'
            ]
          ]
        ],
        'loginRedirect'=>[
          'controller'=>'Users',
          'action'=>'index'
        ],
        'logoutRedirect'=>[
          'controller'=>'Users',
          'action'=>'login',
        ],
        'authError'=>'ログインしてください。',
      ]);
    }

    //ログイン処理
    function login(){
      if ($this->request->isPost()) {
        $user = $this->Auth->identify();
        if (!empty($user)) {
          $this->Auth->setUser($user);
          return $this->redirect($this->Auth->redirectUrl());
        } else {
          $this->Flash->error('ユーザー名かパスワードが間違っています。');
        }
      }
    }

    //ログアウト処理
    public function logout() {
      $this->request->session()->destroy();
      return $this->redirect($this->Auth->logout());
    }

    //認証を使わないページの設定
    public function beforeFilter(Event $event) {
      parent::beforeFilter($event);
      $this->Auth->allow(['login', 'index', 'add']);
    }

    //認証時のロールのチェック
    public function isAuthorized($user = null) {
      if ($user['role'] === 'admin') {
        return true;
      }
      if ($user['role'] === 'user') {
        return false;
      }
      return false;
    }
}
//login.ctp
<div class="users form">
<?= $this->Flash->render('auth') ?>
<?= $this->Form->create() ?>
  <fieldset>
    <legend>アカウント名とパスワードを入力してください。</legend>
    <?= $this->Form->input('username') ?>
    <?= $this->Form->input('password') ?>
  </fieldset>
  <?= $this->Form->button(__('login')); ?>
  <?= $this->Form->end() ?>
</div>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • yukikp

    2019/08/02 18:59

    今見たところ、CakePHP 3.8.1では、
    src\Controller\Component\AuthComponent.php
    の816行目にありました。

    キャンセル

  • yukikp

    2019/08/02 19:30

    どこにつながるか(ちょっと責任感じて)チラチラ見てたら、
    最後は、
    src\Auth\BaseAuthenticate.phpの112行目の
    protected function _findUser($username, $password = null)
    の中に、
    $hasher->check($password, $hashedPassword) と言うのがあって、
    ここで、
    $password(送信されてきた平文のパスワード)$hashedPassword(送信されてきたusernameを使ってデータベースからとってきた暗号化されたパスワード)を比較してます。

    で、この$hasher->checkメソッドは、長々と辿ると、
    src\Auth\DefaultPasswordHasher.phpの、63行目にあり、中身は、
    password_verify($password, $hashedPassword);でした。
    つまりは、単にpassowrd_verify関数でチェックしてるだけでしたね。

    ということは、すみません。
    src\Auth\BaseAuthenticate.phpの112行目の
    protected function _findUser($username, $password = null)関数の中で、$hasher->check($password, $hashedPassword)の前に、

    //ここから
    echo '平文パスワード:' . $password;
    echo '暗号化したあなたのパスワード:' . password_hash($password, PASSWORD_DEFAULT, [] );
    echo 'データベース内のパスワード:' . $hashedPassword;

    die();
    //ここまで追加
    $hasher->check($password, $hashedPassword);

    とかけば、あなたの入れたパスワードとデータベースに保存されているパスワードが比較できるという感じです。

    キャンセル

  • tunnel

    2019/08/02 23:10

    詳細にありがとうございます。地道に探すしか無いんですね、、平文パスとデータベースパスは一致していました。なぜログインできないんでしょう.....。

    キャンセル

回答 1

check解決した方法

0

何故か解決しました。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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