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

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

ただいまの
回答率

90.50%

  • PHP

    24082questions

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

  • HTML

    11521questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

mysqlにてデーターベースからパスワードとidを取り出し、loginフォームを作りたい

解決済

回答 2

投稿 編集

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

mysqlにid,userid,name,passwordを登録し、idとパスワードを取り出しログイン画面を出したいのですが、
うまくいきません。下記にコードとエラー画面、試したことを記載しますので教えて頂ければと思います。
まだ、phpのmysqlについて習って日が浅いのでどなたかご教授頂ければと思います。
よろしくお願いいたします。

ログイン画面 login.php

<?php
require 'password.php';
// セッション開始
session_start();

$db['host'] = "localhost";  // DBサーバのurl
$db['user'] = "testuser";
$db['pass'] = "testpass";
$db['dbname'] = "booksample";

// エラーメッセージの初期化
$errorMessage = "";

// ログインボタンが押された場合
if (isset($_POST["login"])) {
  // 1.ユーザIDの入力チェック
  if (empty($_POST["userid"])) {
    $errorMessage = "ユーザIDが未入力です。";
  } else if (empty($_POST["password"])) {
    $errorMessage = "パスワードが未入力です。";
  } 

  // 2.ユーザIDとパスワードが入力されていたら認証する
  if (!empty($_POST["userid"]) && !empty($_POST["password"])) {
    // mysqlへの接続
    $mysqli = new mysqli($db['host'], $db['user'], $db['pass']);
    if ($mysqli->connect_errno) {
      print('<p>データベースへの接続に失敗しました。</p>' . $mysqli->connect_error);
      exit();
    }

    // データベースの選択
    $mysqli->select_db($db['dbname']);

    var_dump($db['dbname']);

    // 入力値のサニタイズ
    $userid = $mysqli->real_escape_string($_POST["userid"]);
    var_dump($userid);
    // クエリの実行
    $query = "SELECT * FROM users WHERE name = '" . $userid . "'";

    $result = $mysqli->query($query);
    var_dump($query);
    var_dump($result);
    if (!$result) {
      print('クエリーが失敗しました。' . $mysqli->error);
      $mysqli->close();
      exit();
    }



    while ($row = $result->fetch_assoc()) {
      // パスワード(暗号化済み)の取り出し
        $db_hashed_pwd =   $row['password']; 
    }

      var_dump($db_hashed_pwd);

    // データベースの切断
    $mysqli->close();

    // 3.画面から入力されたパスワードとデータベースから取得したパスワードのハッシュを比較します。
    //if ($_POST["password"] == $pw) {
    if (password_verify($_POST["password"], $db_hashed_pwd)) {
      // 4.認証成功なら、セッションIDを新規に発行する
      session_regenerate_id(true);
      $_SESSION["USERID"] = $_POST["userid"];
      header("Location: main.php");
      exit;
    } else {
      // 認証失敗
      $errorMessage = "ユーザIDあるいはパスワードに誤りがあります。";
    } 
  } else {
    // 未入力なら何もしない
  } 
} 


 var_dump($db_hashed_pwd);


?>
<!doctype html>
<html>
  <head>
  <meta charset="UTF-8">
  <title>サンプルアプリケーション</title>
  </head>
  <body>
  <h1>ログイン機能 サンプルアプリケーション</h1>
  <!-- $_SERVER['PHP_SELF']はXSSの危険性があるので、actionは空にしておく -->
  <!--<form id="loginForm" name="loginForm" action="<?php print($_SERVER['PHP_SELF']) ?>" method="POST">-->
  <form id="loginForm" name="loginForm" action="" method="POST">
  <fieldset>
  <legend>ログインフォーム</legend>
  <div><?php echo $errorMessage ?></div>
  <label for="userid">ユーザID</label><input type="text" id="userid" name="userid" value="">
  <br>
  <label for="password">パスワード</label><input type="password" id="password" name="password" value="">
  <br>
  <input type="submit" id="login" name="login" value="ログイン">
  </fieldset>
  </form>
  </body>
</html>


メイン画面 main.php

<?php
session_start();

// ログイン状態のチェック
if (!isset($_SESSION["USERID"])) {
  header("Location: logout.php");
  exit;
}

?>

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>サンプルアプリケーション</title>
  </head>
  <body>
  <h1>ログイン機能 サンプルアプリケーション</h1>
  <!-- ユーザIDにHTMLタグが含まれても良いようにエスケープする -->
  <p>ようこそ<?=htmlspecialchars($_SESSION["USERID"], ENT_QUOTES); ?>さん</p>
  <ul>
  <li><a href="logout.php">ログアウト</a></li>
  </ul>
  </body>
</html>


logout.php

<?php
session_start();

if (isset($_SESSION["USERID"])) {
  $errorMessage = "ログアウトしました。";
}
else {
  $errorMessage = "セッションがタイムアウトしました。";
}
// セッション変数のクリア
$_SESSION = array();

@session_destroy();
?>

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>サンプルアプリケーション</title>
  </head>
  <body>
  <h1>ログイン機能 サンプルアプリケーション</h1>
  <div><?php echo $errorMessage; ?></div>
  <ul>
  <li><a href="login.php">ログイン画面に戻る</a></li>
  </ul>
  </body>
</html>

出ているエラー
Notice: Undefined variable: db_hashed_pwd in C:\xampp\htdocs\login\login.php on line 59
59行目が、var_dumpで調べてもデーターベースからパスワードを引き出せていないというものでした。
空のnullという文字が出てきてしまいます。
試したことは、$query = "SELECT * FROM users WHERE name = '" . $userid . "'";のあとに

$query = "SELECT * FROM users WHERE password;


をつけたり、
hash(sha1,"password")でパスワードを切れていないかを調べましたが、切れていないようです。
データーベース扱いが初めてなものでどなたかご教授頂ければと思います。
宜しくお願い致します。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

+1

/*
    while ($row = $result->fetch_assoc()) {
      // パスワード(暗号化済み)の取り出し
        $db_hashed_pwd =   $row['password']; 
    }
*/
    //$rows = $results->fetch_all();
    $rows = $result->fetch_all();
    header('Content-type: text/plain');
    var_dump($rows);
    exit;

とやってみて、ちゃんと取得できているか確認してみるのはいかがですか?
(間違えてました。修正しました。)

追記

useridが存在していなかったときの処理が入っていないですね。

    if (password_verify($_POST["password"], $db_hashed_pwd)) {
    ↓↓↓↓
    if (isset($db_hashed_pwd) && password_verify($_POST["password"], $db_hashed_pwd)) {

あと、useridnameに入っている、って言うのに違和感を感じますが、どうなんでしょう?
実は、

$query = "SELECT * FROM users WHERE userid = '" . $userid . "'";

だったりしません?

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/06/18 21:12

    有難うございます。上記を確認してみますm(_ _)m

    キャンセル

  • 2017/06/18 21:29

    回答ありがとうございます。上記で確認するとnullということと致命的なエラーという言葉が出てくるようです。私の方でも工夫し見てますので、よい案があれば教えて頂ければと思います。

    キャンセル

  • 2017/06/18 22:08

    コードが間違ってました。訂正しました。

    キャンセル

  • 2017/06/18 22:14

    ありがとうございます
    確認した結果、$result内が全てnull(空)と出ていました。同じような質問した方がいてうまくいったということを書かれていたようなのですが、結果は同じように出ます。
    object(mysqli_result)#2 (5) { ["current_field"]=> int(0) ["field_count"]=> int(4) ["lengths"]=> NULL ["num_rows"]=> int(0) ["type"]=> int(0) } string(0) "" と出るようです。
    お忙しい中すいません、、ご教授頂ければと思います

    キャンセル

  • 2017/06/18 22:24

    $rowsはどうですか?
    Array
    (
    )
    って出ません?

    キャンセル

  • 2017/06/18 22:51

    遅い時間まで回答有難う御座います。はい。この「rows」というものが曲者で定義されていないものです!
    null空の配列というもので出てきます。これを超えない限り中々ログインまでたどり着かないようです。
    私の方でも色々試してみます。

    キャンセル

  • 2017/06/18 23:02

    いえ、曲者ではなく、SELECTの結果が0行なんです。
    つまり、存在しない users をSELECTしています。

    キャンセル

  • 2017/06/18 23:29

    有難うございます。選択された結果がないということですね。了解いたしました。
    上記2点確認致します。遅くまで申し訳ありません。

    キャンセル

  • 2017/06/20 20:41

    色々アドバイス頂きありがとうございます。どうもdb_hashed_password が違うと出るようです。再度、hash化したパスワードを含め、echoで出力してみたいと思います。

    キャンセル

  • 2017/06/21 22:17

    echoで$db_hashed_pwd を調べた結果ですが、きちんとhash化されたパスワードが検出されました。
    おそらくですが、下記部分がおかしいのかなと思います。
    if (password_verify($_POST["password"], $db_hashed_pwd)) {
    // 4.認証成功なら、セッションIDを新規に発行する
    session_regenerate_id(true);
    $_SESSION["USERID"] = $_POST["userid"];
    header("Location: main.php");
    exit;
    } else {
    // 認証失敗
    $errorMessage = "ユーザIDあるいはパスワードに誤りがあります。";
    }
    } else {
    // 未入力なら何もしない
    }
    }

    どなたか書き方をご教授頂ければと思います。宜しくお願い致します。

    キャンセル

  • 2017/06/21 23:17

    59行目のnoticeは直ったんですか?

    キャンセル

  • 2017/06/21 23:49

    テストとして
    password_verify($_POST["password"], $db_hashed_pwd)
    が正常に期待する戻り値になってるか確認するために、
    上記だけを処理するPHPファイル作成してみて
    $_POST["password"]には想定パスワード文字列、
    $db_hashed_pwdには出力された文字列を直接入れてみてチェックしてみてはいかがでしょうか

    ```
    <?php
    $_ret = password_verify('想定してるパスワード', '$db_hashed_pwdの文字列');
    var_dump($_ret);
    ```

    って言う感じですね

    キャンセル

  • 2017/06/22 12:07

    あとheader関数での処理するならば、関数呼ばれる前に文字出力してはいけないはずなのでvar_dumpとかの出力はなくした方がいいかと

    キャンセル

  • 2017/06/22 14:09

    rururu3さん、ぜひ回答してあげてください。

    キャンセル

  • この投稿は削除されました

  • 2017/06/24 21:07

    shi_ueさん、rururu3さんお二方とも有難うございます。rururu3さんの言う通りpassword_verfyでデバックしてみたら、falseということが出てきました。phpのホームページを調べたらpassword_verfyはpassword_hash関数のpassword_default関数を使って登録したパスワードでないと一致しないみたいです。なので、事前に登録した関数がhash256であったみたいなので、従来通り登録したパスワードをhash化し、データーベースに登録したhash化した関数と一致させるequal文を使わせて頂きました。
    お二方とも有難う御座いますm(_ _)m

    キャンセル

checkベストアンサー

0

テストとして
password_verify($_POST["password"], $db_hashed_pwd)
が正常に期待する戻り値になってるか確認するために、
上記だけを処理するPHPファイル作成してみて
$_POST["password"]には想定パスワード文字列、
$db_hashed_pwdには出力された文字列を直接入れてみてチェックしてみてはいかがでしょうか

<?php
$_ret = password_verify('想定してるパスワード', '$db_hashed_pwdの文字列');
var_dump($_ret);

って言う感じですね

あとheader関数での処理するならば、関数呼ばれる前に文字出力してはいけないはずなのでvar_dumpとかの出力はなくした方がいいかと

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

  • PHP

    24082questions

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

  • HTML

    11521questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。