重要
依照下列答案的意见后,客户端能够登录,在没有任何问题,但并没有试图实际浏览的安全网页。 当他试图这样做以后,他回到了与“请登录”错误像以前一样登录项。 很多挠头之后,事情非常简单浮现在脑海-客户正在访问的网站与http://www.example.com/admin登录脚本,一切都重定向到http://example.com ,所以会议它一直在寻找另一个域设置的cookie。 这也解释了为什么他在第一次登录的问题,但没有后续时间 - 脚本重定向他的登录表单不带www。
速战速决是写.htaccess文件去除WWW,问题就迎刃而解了。 当然,这也登录脚本,我会改进将来使用内处理。
原帖
我开发PHP和MySQL基础的网站有家酿CMS和登录系统。 我的CMS是唯一的每一个客户,它已经相当的取悦观众 - 不幸的是,同样是没有我的登录系统也是如此。 下面是一个长期的职位,但我需要覆盖的细节,试图找到一个解决方案。 忍耐一下..
该系统是相当简单的,如果不是有点沉重。 每个用户具有存储在MySQL表盐腌哈希,旁边的盐。 当用户登录时,他们的盐是检索和提交的密码变成盐腌哈希。
如果提交的盐渍哈希值匹配存储在表中的一个,用户进行身份验证。 如他们的名字,最后一个IP地址和帐户级别(在大多数网站3级)的详细信息存储在分配给会话变量数组。 然后,他们将被重定向到受限制的站点的登陆页面,他们登录(只或管理/ CMS成员)。
安全网页包括检查是否含有他们的详细信息会话变量存在一个较小的auth.php文件。 如果不是,他们将被重定向到与读取的错误消息的网站的登录表格“请登录”。 如果存在,他们被允许继续并存储在数组中的细节被分配给变量。
许多用户报告的问题是,他们往往需要登录多次被反弹到保持登录形式与“请登录”错误信息,或者导航到另一个页面的安全现场并随机获得反弹具有相同的错误登录。 因此,会话变量似乎既不会得到设置或它正在正常使用本网站的过程中由于某种原因被清除。
第一个问题从来没有发生在我身上 - 在设备和网络的大量 - 和我一直在使用他们的笔记本电脑在客户的办公室亲眼目睹了。 我让他们连接到我的移动热点,也没有改变。 然而,他们能够登录,而无需使用我的笔记本电脑和我的热点连接的任何问题。 不幸的是,我无法用我的笔记本电脑连接到他们的网络,使变量不能被排除。
* 注- *我忘了最初提及的是,系统正常工作的问题客户,他们使用正确的凭据登录两次或三次之后。 随后的登录尝试,而他们的浏览器保持打开状态,往往没有问题后执行。 此外,登录页面破坏了会议。
下面是每个阶段,首先是登录脚本的代码:
的login.php
<?php
putenv("TZ=US/Eastern");
if (array_key_exists('site', $_POST)) {
$authenticate = new loginUser($_POST['username'], $_POST['password'], $_POST['site'], $_SERVER['REMOTE_ADDR']);
}
//Authenticate and log-in
class loginUser {
private $memDB, $username, $password, $site, $ip_address;
//Clean input variables
private function clean($str) {
$str = @trim($str);
if(get_magic_quotes_gpc()) {
$str = stripslashes($str);
}
return $str;
}
//Construct variables
function __construct($username, $password, $site, $ip_address) {
session_start();
$this->memDB = new PDO('mysql:host=localhost;dbname=exampleDB', 'exampleUser', 'examplePassword');
$this->username = $this->clean($username);
$this->password = $this->clean($password);
$this->site = $site;
$this->ip_address = $ip_address;
$this->authUser();
}
//Validate username
private function validateUsername($username) {
$checkUsername = $this->memDB->prepare("SELECT COUNT(*) FROM accounts WHERE username = ?");
$checkUsername->execute(array($username));
return $checkUsername->fetchColumn();
}
//Obtain and set account details
private function accountDetails() {
$fetchAccountDetails = $this->memDB->prepare("SELECT id, name_f, name_l, ipAddr, lastLogin, accountLevel, isActive
FROM accounts WHERE username = ?");
$fetchAccountDetails->execute(array($this->username));
$accountDetails = $fetchAccountDetails->fetch();
$this->updateLogin();
return $accountDetails;
}
//Update last login details
private function updateLogin() {
$updateLogin = $this->memDB->prepare("UPDATE accounts SET ipAddr = ?, lastLogin = DATE_ADD(NOW(), INTERVAL 1 HOUR) WHERE username = ?");
$updateLogin->execute(array($this->ip_address, $this->username));
}
public function authUser() {
$loginErr = array(); //Array for holding login error message
$loginErrFlag = false; //Boolean for error
//Validate submitted $_POST elements
if (!$this->username) {
$loginErr[] = "Username missing";
$loginErrFlag = true;
}
if (!$this->password) {
$loginErr[] = "Password missing";
$loginErrFlag = true;
}
if ($this->username && $this->validateUsername($this->username) == 0) {
$loginErr[] = "Username invalid";
$loginErrFlag = true;
}
if (!$loginErrFlag) {
//Fetch the password and SALT to compare to entered password
$validatePW = $this->memDB->prepare("SELECT password, salt FROM accounts WHERE username = ? LIMIT 1");
$validatePW->execute(array($this->username));
$passwordResult = $validatePW->fetch();
$dbPW = $passwordResult['password'];
$dbSalt = $passwordResult['salt'];
//Compare entered password to SALT + hash
$hashPW = hash('sha512', $dbSalt . $this->password);
if ($hashPW === $dbPW) {
//Logged in
$_SESSION['CVFD-USER-DETAILS'] = $this->accountDetails();
//Redirect to secure landing page for log-in origin (Members or Admin)
//Adding SID is a recent attempt to handle log-in problems
header("Location: http://example.com/$this->site/$this->site-main.php?" . SID);
//session_write_close() was here but was removed
exit();
} else {
//Password invalid
$loginErr[] = "Please check your password and try again";
$_SESSION['CVFD_LOGIN_ERR'] = $loginErr;
//Redirect to the log-in for the origin
header("Location: http://example.com/$this->site");
session_write_close();
exit();
}
} else {
$_SESSION['CVFD_LOGIN_ERR'] = $loginErr;
header("Location: http://example.com/$this->site");
session_write_close();
exit();
}
}
}
?>
auth.php
<?php
session_start();
if (!isset($_SESSION['CVFD-USER-DETAILS']) || $_SESSION['CVFD-USER-DETAILS'] == '') {
//Not logged in
$_SESSION['CVFD_LOGIN_ERR'] = array('Please login');
header('Location: http://example.com/members');
session_write_close();
exit();
} else {
$userDetails = $_SESSION['CVFD-USER-DETAILS']; //Assign user details array to variable
//Check to see if account is active
$accountStatus = $userDetails['isActive'];
$accountLevel = $userDetails['accountLevel'];
if ($accountStatus == 0) {
//Account is not yet active (pending Admin activation)
$_SESSION['CVFD_LOGIN_ERR'] = array('Your account is suspended or pending activation');
header('Location: http://example.com/members');
session_write_close();
exit();
} else {
$CVFDFirstName = $userDetails['name_f'];
$CVFDLastName = $userDetails['name_l'];
$CVFDLastLogin = date("m/d/Y H:i:s", strtotime($userDetails['lastLogin']));
$CVFDAccountLevel = $userDetails['accountLevel'];
$CVFDIPAddr = $userDetails['ipAddr'];
}
}
?>
这里是auth.php是如何包含在安全文件 -
<?php
if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) ob_start("ob_gzhandler"); else ob_start();
require($_SERVER['DOCUMENT_ROOT'] . '/members/includes/handlers/handler.auth.php');
任何帮助,将不胜感激。 相当一个谜..
谢谢!