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

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

新規登録して質問してみよう
ただいま回答率
85.51%
セキュリティー

このタグは、コンピューターシステムの安全性やデータの機密性に関連したトピックの為に使われます。

PHP

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

Q&A

解決済

2回答

2738閲覧

hash_verify()がうまく結果をかえさない

earnest_gay

総合スコア615

セキュリティー

このタグは、コンピューターシステムの安全性やデータの機密性に関連したトピックの為に使われます。

PHP

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

1グッド

1クリップ

投稿2016/06/30 19:26

編集2016/06/30 19:46

下記で動作テストしてみました。

$nama = filter_input(INPUT_POST,password); $hash = password_hash(filter_input(INPUT_POST,password),PASSWORD_DEFAULT); $result = password_verify($nama,$hash); echo '生パス:'.$nama .'<br />'; echo 'ハッシュ:'.$hash .'<br />'; var_dump($result);

結果はbool(true)です。

しかし、実際にDBにあるハッシュ化されたパスワードと生パスを比較するとfalseになってしまいます。

原因は何が考えられますでしょうか?

実際の記述です。

<?php $email = filter_input(INPUT_POST,email); $password = filter_input(INPUT_POST,password); $sql = "SELECT * FROM user_data WHERE email = ? AND password = ?"; $stmt = $pdo->prepare($sql); $stmt->execute([ $email, $password ]); $hitdata =$stmt->fetch(); if(isset($email) && isset($password)) { if($email === $hitdata[email] && password_verify($password,$hitdata[password]) ){ $_SESSION['email'] = h(filter_input(INPUT_POST,email)); header('Location: login1.php'); } else { $messe = "ログインできませんでした"; } } ?> <form action="" method="post"> <p>E-mail</p> <input type="email" name="email" id="email" value="<?php echo h(filter_input(INPUT_POST,email)); ?>"/ maxlength="255"> <p>Password</p> <input type="password" name="password" id="password" value="<?php echo h(filter_input(INPUT_POST,password)); ?>" maxlength="255" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}" title="6文字以上で1文字以上の数字、小文字アルファベット、大文字アルファベットがそれぞれ含まれていること"> <p><input type="checkbox" id="save" name="save" value="on" />次回からは自動的にログインする</p> <input type="submit" value="ログイン"> <br /> <?php echo $messe ?> </form>

多分、
echo $hitdata['email'];
echo $hitdata['password'];

で何も出力されないので

$sql = "SELECT * FROM user_data WHERE email = ? AND password = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([
$email,
$password
]);

のところで

password = ?

password = 生パスワード

になっているのでデータがヒットしていないから
echo $hitdata['email'];
echo $hitdata['password'];
に何も入っていないと思うのですが、

こういう場合どうしたらよろしいでしょうか?

退会済みユーザー👍を押しています

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

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

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

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

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

guest

回答2

0

ベストアンサー

PHPでログイン機能を実装するチュートリアル #1

こちらの password_hash() の説明を参考にしてみてください。

投稿2016/07/01 00:53

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

earnest_gay

2016/07/01 06:56

回答ありがとうございます。 要は $sql = "SELECT * FROM user_data WHERE email = ? AND password = ?"; じゃなくて $sql = "SELECT * FROM user_data WHERE email = ? "; という風にメールアドレスだけでデータ取得しておいて アドレスからハッシュ化パス引っ張ってきて、 password_verify()で照合したらいいということでしょうか?
退会済みユーザー

退会済みユーザー

2016/07/01 06:56

そういうことです
earnest_gay

2016/07/01 06:56

理解です! ありがとうございます!
guest

0

ハッシュが保存されているなら、executeに渡すべき値はこうなるかと思いますが…

PHP

1$stmt->execute([ 2 $email, 3 password_hash($password,PASSWORD_DEFAULT) 4 ]);

###追記
password_hashの使い方が誤っているとの指摘を受けたので修正。
そもそもDB上でパスワードが合っているかを確認できないので、DBに保存されたハッシュ値を受け取って、そのあと生のパスワードデータとハッシュ値を使ってpassword_verifyすればいいんではないでしょうか。

PHP

1$sql = "SELECT * FROM user_data WHERE email = ?"; 2$stmt = $pdo->prepare($sql); 3$stmt->execute([ 4$email 5]); 6if(password_verify($password, $stmt["password"])) { 7 // OK 8}

投稿2016/06/30 23:37

編集2016/07/01 06:55
masaya_ohashi

総合スコア9206

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

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

退会済みユーザー

退会済みユーザー

2016/07/01 00:55

password_hashの返す値は、同じパスワードであっても、salt を含むため、返す値は一定ではありません。
earnest_gay

2016/07/01 06:50

回答ありがとうございます。 ハッシュ値は毎回ことなるので、それでは取得できないんです... $password = "test"; echo password_hash($password,PASSWORD_DEFAULT) ↑毎回違うものが出力されます。 WHERE句でpassword = ?の分部で?に入っているのは入力したパスワード(生パス)で しかし実際DBへ登録されているのはハッシュ化されたパスワードであるが故に いくら比較しても取得できていないのだと思います... ということは $sql = "SELECT * FROM user_data WHERE email = ? AND password = ?"; $stmt = $pdo->prepare($sql); $stmt->execute([ $email, $password,PASSWORD_DEFAULT) ]); の分部を工夫しないといけないと思うのですが、それが分からず... どうやってDBのハッシュ化されたパスを比較させるか?ですかね... password_verify(生パス,ハッシュ化されたパス)
earnest_gay

2016/07/01 07:02

ohashiさんもありがとうございます! 当初生パスのままログイン画面作っていて、 ハッシュ化対応はあとからしようと思っていて今になってログイン画面改修しています???? でも、他の画面の作っていたこともあって当初よりはすんなり理解しながら記述できていたりするところもあります。 当初はログイン画面作るだけで2週間かかったりしてましたが、すんなりできると楽しくなってきました。 これもohashiさんやShibuyaさんやみなさんのアドバイスのおかげです。 本当にありがとうございます。
masaya_ohashi

2016/07/01 08:03

とてもよいことです。これからも精進してください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問