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

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

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

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

Q&A

解決済

3回答

4402閲覧

cakephp3でパスワードリマインダー実装

lovelydai

総合スコア38

CakePHP

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

0グッド

1クリップ

投稿2017/09/25 02:50

こんにちは、Cakephp3でログインできるシステムを作っています。

ログインしていない状態で、顧客番号とログインIDと現在パスワード、新しいパスワードを入れることでパスワードを更新させる機能を実装したいです。利用者登録するとランダムでパスワードが発行され、メールでお知らせする仕組みなのでログインなしでもパスワードが変更できるようにしたいです。

認証はCakephp3のAuthを利用して作り、問題なく動いています。
そこで、ページからPOSTで入力されたデータを利用し、DBに暗号化されたパスワードと一致するかを比較し、一致した場合は利用者が入力した新パスワードで更新する機能を作りたくて以下のようにコードを作ってみましたが、エラーが出てしまいました。

php

1 //UsersController.phpの中 2 3public function change() 4 { 5 6 if ($this->request->is('post')) 7 { 8 9 $salt_key = '//システムの基本値64Bitのコードを入れました。'; 10 11 $customer_no = $this->request->data['customer_no']; 12 $user_id = $this->request->data['user_id']; 13 $password_now = $this->request->data['password_now']; 14 $password_new = $this->request->data['password_new']; 15 $password_check = $this->request->data['password_check']; 16 17 $user = $this->Users->find()->where(['customer_no' => $customer_no]) 18 ->andWhere(['user_id' => $user_id]); 19 20 $pwd = $user->password; // エラー: Undefined property: Cake\ORM\Query::$password 21 $password = Security::decrypt($pwd,$salt_key); 22 23 if ($password === $password_now) 24 { 25 26 if($password_new === $password_check) 27 { 28 $user->password = Security::hash($password_new,$salt_key); 29 $user->modifier = $user_id; 30 $this->Users->save($user); 31 32 $this->Flash->success(__('Success to change password, plz login with new password.')); 33 return $this->redirect(['action' => 'login']); 34 } 35 else { 36 $this->Flash->error(__('Failed to change password, plz check your informaion.')); 37 } 38 39 } 40 } 41 }

すると、このようなエラーメッセージが画面にでてしまいます。
イメージ説明

$passwordという変数が定義されてないと出るし、Decryptもそれでうまく動いてなさそうです。そもそも、Hash化されてDBにあるパスワードをこのように無理やり読み込んで復号化し、POSTデータと比較してまた暗号化するというやり方が正しいか?という疑問もあります。
また、ControllerとModel(UsersTable.php)に分けてコードを書く必要があるか?と思っていますが…データベースに接続してパスワードの一致を確認する処理は、コントローラーではなくてModelか、Entityですることかな?とかのもやもや感があります。

何かアドバイスや参考できることがあればぜひお願いしたいです。
どうぞよろしくお願いいたします。

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

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

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

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

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

m.ts10806

2017/09/25 05:20 編集

そもそも$userは正しく想定の情報が取得できているのでしょうか?他のrequestも同様にご確認ください。
lovelydai

2017/09/25 06:35

Queryの実行されてなかったです。ご指摘ありがとうございます。
guest

回答3

0

$user = $this->Users->find()->where(['customer_no' => $customer_no]) ->andWhere(['user_id' => $user_id]);

のあとに

$user = $user->first();

としたら$user->passwordが取得できるようになるかと思われますがどうでしょう?

投稿2017/09/25 06:31

ranchu

総合スコア51

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

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

lovelydai

2017/09/25 06:35

おかげさまで収得できました!ありがとうございます。
guest

0

私も同じ事やりたくて、lovelydaiさんのコードで行けました。ありがとうございます。感謝です。

投稿2019/01/14 09:36

KazukiKudo

総合スコア37

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

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

0

自己解決

解決しました。
原因は、ハッシュ化されたものをチェックする場合DefaultPasswordHasherを利用しないといけない、ということでした。具体的には、$hasher->check()で一致しているか確認し、save()で更新することで正常に動くようになりました。

php

1 2use Cake\Auth\DefaultPasswordHasher; // 追加 3 4class UsersController extends AppController 5{ 6 // コード省略 7 public function change() 8 { 9 10 if ($this->request->is('post')) 11 { 12 13 $user_id = $this->request->data['user_id']; 14 $password_now = $this->request->data['password_now']; 15    $password_new = $this->request->data['password_new']; 16 17 $query = $this->Users->find()->where(['user_id' => $user_id]); 18 $user = $query->first(); 19 20 if($user) 21 { 22 // 利用者情報の収得に成功した場合 23 $hasher = new DefaultPasswordHasher(); 24 $equal_check = $hasher->check($password_now, $user->password); 25 26 if($equal_check) 27 { 28 $user->password = $password_new; 29 if ($this->Users->save($user)) 30 { 31 $this->Flash->success(__('パスワードを成功的に更新しました。新しいログイン情報でログインしてください。')); 32 return $this->redirect(['action' => 'login']); 33 } 34 else 35 { 36 $this->Flash->error(__('パスワードの更新に失敗しました。ログイン情報を確認しやり直してください。')); 37 } 38 } 39 } 40 } 41}

投稿2017/09/26 06:36

lovelydai

総合スコア38

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問