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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

Q&A

解決済

3回答

4453閲覧

ログイン認証について

ssk

総合スコア332

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

0グッド

0クリップ

投稿2016/06/12 06:17

編集2016/06/13 05:52

ログイン認証ができません。。

$hashesをvar_dumpすると

PHP

1array(1) { ["08011111111"]=> string(12) "$2y$10$BOqI." }

と、データベースから情報は取れているようです。
ユーザ認証できないのは何が原因でしょうか?

【参考URL】
http://qiita.com/mpyw/items/bb8305ba196f5105be15

PHP

1<?php include('header.php'); ?> 2<?php 3require_once __DIR__ . '/functions.php'; 4require_unlogined_session(); 5ini_set('display_errors', true); 6error_reporting(E_ALL); 7//ユーザから受け取ったユーザ名とパスワード 8 $tel_mail = filter_input(INPUT_POST, 'tel_mail'); 9 $password = filter_input(INPUT_POST, 'password'); 10 11try{ 12 //データベース接続 13 include('./conf/db_con.php'); 14 $sql ='SELECT * FROM user WHERE (tel=:tel_mail OR mail=:tel_mail)'; 15 $stmt=$dbh->prepare($sql); 16 $data[':tel_mail'] = $tel_mail; 17 $stmt->execute($data); 18 $dbh = null; 19 //1行ずつ取り出し 20 $rec = $stmt->fetch(PDO::FETCH_ASSOC); 21 // 事前に生成したユーザごとのパスワードハッシュの配列 22 $hashes = [ 23 $tel_mail => $rec['password'], 24 ]; 25}catch(Exception $e){ 26 print 'ただいま障害により大変ご迷惑をお掛けしております。'; 27 exit(); 28} 29 30// POSTメソッドのときのみ実行 31if ($_SERVER['REQUEST_METHOD'] === 'POST') { 32 if ( 33 validate_token(filter_input(INPUT_POST, 'token')) && 34 password_verify( 35 $password, 36 isset($hashes[$tel_mail]) 37 ? $hashes[$tel_mail] 38 : '$2y$10$abcdefghijklmnopqrstuv' // ユーザ名が存在しないときだけ極端に速くなるのを防ぐ 39 ) 40 ) { 41 // 認証が成功したとき 42 // セッションIDの追跡を防ぐ 43 session_regenerate_id(true); 44 // ユーザ名をセット 45 session_start();//合言葉を決める 46 $_SESSION['login']=1;//ログインOKの証拠を残す 47 $_SESSION['user_id']=$rec['user_id']; 48 // ログイン完了後に / に遷移 49 header('Location: /index.php'); 50 exit; 51 } 52 // 認証が失敗したとき 53 // 「403 Forbidden」 54 http_response_code(403); 55} 56 57header('Content-Type: text/html; charset=UTF-8'); 58 59?> 60<main id="regist"> 61<div class="container"> 62 <section class="container"> 63 <?php var_dump($hashes[$tel_mail]); ?> 64 <form class="form-horizontal" action="" method="post"> 65 <fieldset> 66 <div class="clearfix"></div><br> 67 <div class="input-group input-group-lg"> 68 <span class="input-group-addon"><i class="glyphicon glyphicon-user red"></i></span> 69 <input type="text" class="form-control" placeholder="電話番号またはメールアドレス" name="tel_mail"> 70 </div> 71 <div class="clearfix"></div><br> 72 <div class="input-group input-group-lg"> 73 <span class="input-group-addon"><i class="glyphicon glyphicon-lock red"></i></span> 74 <input type="password" class="form-control" placeholder="パスワード" name="password"> 75 </div> 76 <div class="clearfix"></div> 77 <div class="col-sm-12"> 78 <button type="submit" class="btn btn-default center-block">ログイン</button> 79 </div> 80 </fieldset> 81 <input type="hidden" name="token" value="<?=h(generate_token())?>"> 82</form> 83<?php if (http_response_code() === 403): ?> 84<p style="color: red;">ユーザ名またはパスワードが違います</p> 85<?php endif; ?> 86 </section> 87</div> 88</main> 89<?php include('footer.php'); ?>

functions.php

PHP

1<?php 2 3/** 4 * ログイン状態によってリダイレクトを行うsession_startのラッパー関数 5 * 初回時または失敗時にはヘッダを送信してexitする 6 */ 7function require_unlogined_session() 8{ 9 // セッション開始 10 @session_start(); 11 // ログインしていれば / に遷移 12 if (isset($_SESSION['user_id'])) { 13 header('Location: /'); 14 exit; 15 } 16} 17function require_logined_session() 18{ 19 // セッション開始 20 @session_start(); 21 // ログインしていなければ /login.php に遷移 22 if (!isset($_SESSION['user_id'])) { 23 header('Location: ./login.php'); 24 exit; 25 } 26} 27 28/** 29 * CSRFトークンの生成 30 * 31 * @return string トークン 32 */ 33function generate_token() 34{ 35 // セッションIDからハッシュを生成 36 return hash('sha256', session_id()); 37} 38 39/** 40 * CSRFトークンの検証 41 * 42 * @param string $token 43 * @return bool 検証結果 44 */ 45function validate_token($token) 46{ 47 // 送信されてきた$tokenがこちらで生成したハッシュと一致するか検証 48 return $token === generate_token(); 49} 50 51/** 52 * htmlspecialcharsのラッパー関数 53 * 54 * @param string $str 55 * @return string 56 */ 57function h($str) 58{ 59 return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); 60} 61?>

データベースはuserというテーブルで
tel
mail
password

と、構成されています。

【追記】
エラーは発生していません。

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

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

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

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

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

omusoba

2016/06/12 07:27

実際に今のコードで動かしてログイン認証ができないということはどこでエラーが発生していますか?
退会済みユーザー

退会済みユーザー

2016/06/12 09:45

回答者が回答に必要な最低限の情報は提示してください。
ssk

2016/06/12 09:48

Kosuke_Shibuya様 1ページすべての内容を提示したのですが その他にどのような情報が必要でしょうか?
退会済みユーザー

退会済みユーザー

2016/06/12 09:52 編集

どこまで処理が進んでいるのか。requireしているファイルの中身とか、デバッグもできませんよ。回答者はコードをただ眺めて回答しているわけじゃありません。実際にコードを実行してみて問題点を探ります。DBの定義だって必要な情報ではありませんか?
omusoba

2016/06/12 10:11 編集

そうですね....答えを聞く限り、認証できないということはhttp_response_code(403);に進むということですよね?validate_tokenと password_verifyの結果自体はデバック時などに確認して結果はどうでしたか?
ssk

2016/06/13 05:53

Kosuke_Shibuya様 情報を追加しました。 いかがでしょう、、よろしくお願い致します。
ssk

2016/06/13 05:54

omusoba様 http_response_code(403);に進むということですよね? ↑仰る通りです。
guest

回答3

0

何でハッシュ値生成しましたか?
md5 でしょうか
SHA256 でしょうか
ファイルの文字コードと
DBテーブルの文字コードが違ったりすると
はじかれます。

切り分けとしては、
その辺でしょうかね。

投稿2016/06/13 08:16

YK1037

総合スコア236

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

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

ssk

2016/06/13 12:32

ご回答ありがとうございました。 無事、実装することができました。
guest

0

ベストアンサー

header.phpのincludeはロジックが全て終わってからにしてください.ob_startが最初に実行されていない限り,認証などに絡むHTTPヘッダが正しく送信されなくなってしまいます.最初にロジックを全て固めて,HTMLはやるべきことを全てやってから出し始める,というのを徹底してください.


【修正案】

php

1<?php 2 3// エラーをデバッグのために全表示する 4ini_set('display_errors', true); 5error_reporting(E_ALL); 6 7// 必要な関数群を読み込む 8require_once __DIR__ . '/functions.php'; 9 10// 未ログインセッションを要求し,ログイン済みの場合は / に遷移する 11require_unlogined_session(); 12 13// ユーザから受け取ったユーザ名,パスワード,CSRFトークン 14$tel_mail = filter_input(INPUT_POST, 'tel_mail'); 15$password = filter_input(INPUT_POST, 'password'); 16$token = filter_input(INPUT_POST, 'token'); 17 18// POSTメソッドのときのみ実行 19if ($_SERVER['REQUEST_METHOD'] === 'POST') { 20 21 try { 22 23 // データベースから情報取得 24 // (提示されていないdb_con.phpの書き方が怪しいので敢えて書き直します) 25 $pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', '', [ 26 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // SQL実行時のエラーもPDOExceptionに変換する 27 ]); 28 $stmt = $pdo->prepare('SELECT * FROM user WHERE tel = :tel_mail OR mail = :tel_mail LIMIT 1'); 29 $stmt->execute(compact('tel_mail')); // compactは ['tel_mail' => $tel_mail] の省略形 30 $user = $stmt->fetch(PDO::FETCH_ASSOC); 31 32 } catch (PDOException $e) { 33 34 // PDOでエラーが発生したとき 35 // テキストで「500 Internal Server Error」 36 header('Content-Type: text/plain; charset=UTF-8'); 37 http_response_code(500); 38 exit('データベース障害: ' . $e->getMessage()); 39 40 } 41 42 // CSRFバリデーションおよびパスワードハッシュの検証 43 // (ユーザ名が存在しないときだけ極端に速くなるのも防ぐ) 44 if ( 45 validate_token($token) && 46 password_verify($password, $user ? $user['password'] : '$2y$10$abcdefghijklmnopqrstuv') 47 ) { 48 // 認証が成功したとき 49 // セッションIDの追跡を防ぐ 50 session_regenerate_id(true); 51 $_SESSION['user_id'] = $user['user_id']; // (ログインの証拠はこれの存在を見ればOK) 52 // ログイン完了後に / に遷移 53 header('Location: /'); 54 exit; 55 } 56 57 // 認証が失敗したとき 58 // 「403 Forbidden」 59 http_response_code(403); 60 61} 62 63// HTMLとして表示 64header('Content-Type: text/html; charset=UTF-8'); 65 66?> 67<?php include('header.php'); ?> 68<main id="regist"> 69 <div class="container"> 70 <section class="container"> 71 <form class="form-horizontal" action="" method="post"> 72 <fieldset> 73 <div class="clearfix"></div><br> 74 <div class="input-group input-group-lg"> 75 <span class="input-group-addon"><i class="glyphicon glyphicon-user red"></i></span> 76 <input type="text" class="form-control" placeholder="電話番号またはメールアドレス" name="tel_mail" value="<?=h($tel_mail)?>"> 77 </div> 78 <div class="clearfix"></div><br> 79 <div class="input-group input-group-lg"> 80 <span class="input-group-addon"><i class="glyphicon glyphicon-lock red"></i></span> 81 <input type="password" class="form-control" placeholder="パスワード" name="password"> 82 </div> 83 <div class="clearfix"></div> 84 <div class="col-sm-12"> 85 <button type="submit" class="btn btn-default center-block">ログイン</button> 86 </div> 87 </fieldset> 88 <input type="hidden" name="token" value="<?=h(generate_token())?>"> 89 </form> 90<?php if (http_response_code() === 403): ?> 91 <p style="color: red;">ユーザ名またはパスワードが違います</p> 92<?php endif; ?> 93 </section> 94 </div> 95</main> 96<?php include('footer.php'); ?>

投稿2016/06/13 06:33

編集2016/06/13 06:54
mpyw

総合スコア5223

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

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

ssk

2016/06/13 12:33

こちらの方法で実装することができました。 <?php include('header.php'); ?>の記載が問題でした。
guest

0

php

1array(1) { ["08011111111"]=> string(12) "$2y$10$BOqI." }

間違いなくこのパスワードは明らかにおかしいです。最低64文字以上になりはず。

投稿2016/06/12 09:48

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

ssk

2016/06/13 05:56

DBのpasswordが8文字以内になっていました。 64文字にしたところ、以下のようになりました。 array(1) { ["08022222222"]=> string(60) "$2y$10$fkO3opYbOEKxwi6BmD5P0OPnUl2FaiyLY1wfcy/OVGmFMWgE4hIcu" } しかし、まだログインはできないです。
ssk

2016/06/13 12:32

回答ありがとうございました>< 解決することができました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問