私が書いたPHPログインクラスがあります:
include('../../datatypes/User.datatype.php');
$usher = new Authenticator;
$usher->checkCreds();
$usher->ensureHasAccess();
Class Authenticator {
protected $user;
protected function getCreds() {
if (!isset($_POST['adminLogin']))
echo('There was an error handling your request');
else if (empty($_POST['username']) || empty($_POST['password']))
echo('You must enter a username and password');
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$password = md5(filter_input(INPUT_POST, 'password', FILTER_SANITIZE_STRING));
$this->user = new User;
$this->user->username = $username;
$this->user->password = $password;
}
public function checkCreds() {
$this->getCreds();
if (empty($this->user->username) || empty($this->user->password))
echo('There was an error processing your request');
include('../../../dbconnect.php');
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name;", $db_user, $db_password);
$stmt = $pdo->prepare('SELECT userID, userFName FROM Users WHERE username = ? AND password = ?');
$stmt->bindParam(1, $this->user->username);
$stmt->bindParam(2, $this->user->password);
$stmt->bindColumn(1, $tblUserID, PDO::PARAM_INT);
$stmt->bindColumn(2, $userFName, PDO::PARAM_STR);
$stmt->execute();
$stmt->fetch(PDO::FETCH_BOUND);
if ($stmt->rowCount() != 1)
echo "{\"result\" : false}";
$this->user->tblUserID = $tblUserID;
$this->user->firstName = $userFName;
$status = true;
}
protected function createSessionID() {
$seshID = mt_rand(99999, 1000000000);
return $seshID;
}
protected function startSession() {
if ($status === false)
echo "{\"result\" : false}";
echo "{\"result\" : true}";
session_start();
$_SESSION['id'] = $this->createSessionID();
$secret = crypt($_SESSION['id']);
$_SESSION['lastInsert'] = 0;
$_SESSION['tblUserID'] = $this->user->tblUserID;
$_SESSION['firstName'] = $this->user->firstName;
$_SESSION['logged-in'] = true;
header('Location: ../../index.php?=admin');
}
public function ensureHasAccess() {
$grantedAccess = $this->startSession();
if ($grantedAccess === false)
header('Location: ../../error/403.php');
echo "{\"result\" : true}";
session_start();
}
}
注: テストには MD5 を使用していますが、それ以外の場合は bcrypt を使用します。また、これは次のように AJAX がなくても問題なく機能します。
$('#login_form').on('submit', function(e) {
e.preventDefault();
var $form = $(this);
var username = $('#username').val();
var password = $('#password').val();
if (username == '' || password == '')
$('span#errForm').fadeIn(200).text('You must enter a username and password');
$.ajax({
type: 'post',
url: '/classes/login/Authenticator.php',
dataType: 'json',
data: $form.serialize(),
success: function(data) {
if (data.result === false)
$('span#errForm').fadeIn(200).text('Invalid username or password');
else
window.location = '/index.php?=admin';
}
});
return false;
});
このフォームを処理するには:
<div class="actionDiv">
<span id="errForm"></span>
<form id="login_form" action="./classes/login/Authenticator.php" method="post" onsubmit="return false;">
<p>username: <input type="text" name="username" id="username" /></p>
<p>password: <input type="password" name="password" id="password" /></p>
<p><input type="submit" name="adminLogin" value="Log in" id="adminLogin" /></p>
</form>
<p><a id="cancelLogin" href="">Cancel</a></p>
</div>
問題は、フォーム データが入力されていない場合、または無効なフォーム データが入力されている場合でも、ログインが発生することです。正しいログイン データを使用すると、送信ボタンをクリックしても何も起こらず、ページを手動で更新する必要があります。フォーム データが入力されていない場合、その旨のメッセージが表示されますが、ページを更新すると空のセッションが作成されるだけです。
使ってみerror: function(data)
ましたが変わりません。コンソールにもエラーは表示されません。ここで何が欠けていますか?クラス内にあるPHPはこれに影響しますか?
編集: Chrome 開発者ツールでは、ネットワークの下で、Authenticator.php のステータスは、適切なログインと不適切なログインの両方で 200 ok です。