php脚本 - 一次只允许一个会话

时间:2012-12-02 11:08:19

标签: php mysql session login

请帮助我一次只验证一个会话,请看下面的脚本,该脚本目前允许相同的用户名登录任意数量的会话。

我不确定验证会话的时间和地点,帮助我只添加那几行可以验证会话的用户名。

<?php // accesscontrol.php
include_once 'common.php';
include_once 'db.php';

session_start();

$uid = isset($_POST['uid']) ? $_POST['uid'] : $_SESSION['uid'];
$pwd = isset($_POST['pwd']) ? $_POST['pwd'] : $_SESSION['pwd'];

if(!isset($uid)) {
  ?>
  <!DOCTYPE html PUBLIC "-//W3C/DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
<title>Login</title>
<meta http-equiv="Content-Type"
  content="text/html; charset=iso-8859-1" />
<head>
<style type="text/css">
<!--
.style1 {
    font-size: 16px;
font-family: Verdana, Arial, Helvetica, sans-serif;
}
.style3 {
    font-size: 12px;
    font-family: Verdana, Arial, Helvetica, sans-serif;
}

body {
background-color: #D7F0FF;
margin-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
}

-->
</style>

  </head>
<body>
  <h1 class="style1"> <br><br>Amogh Site - Login Required </h1>
  <span class="style3"><br>
  You <strong>must login to access this area </strong>of the site. <br>
  <br>
  If you are not a registered user, please contact your Admin
     to sign up for instant access!</span>
  <p><form method="post" action="<?=$_SERVER['PHP_SELF']?>">

<span class="style3">User ID:&nbsp;&nbsp;&nbsp;&nbsp;    
<input type="text" name="uid" size="12" />
<br>
<br />
Password:</span>    
<input type="password" name="pwd" SIZE="12" />
<br>
<br />
<input type="submit" value="Login" />
  </form></p>

</body>
  </html>
  <?php
  exit;
}

$_SESSION['uid'] = $uid;
$_SESSION['pwd'] = $pwd;

dbConnect("hitek_svga3");
$sql = "SELECT * FROM user WHERE
    userid = '$uid' AND password = '$pwd'";
$result = mysql_query($sql);
if (!$result) {
error('A database error occurred while checking your '.
    'login details.\\nIf this error persists, please '.
    'contact you@example.com.');
}

if (mysql_num_rows($result) == 0) {
  unset($_SESSION['uid']);
  unset($_SESSION['pwd']);
  ?>

  <!DOCTYPE html PUBLIC "-//W3C/DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title> Access Denied </title>
    <meta http-equiv="Content-Type"
      content="text/html; charset=iso-8859-1" />
    <style type="text/css">
<!--
.style1 {
    font-size: 16px;
    font-family: Verdana, Arial, Helvetica, sans-serif;
}
.style3 {
font-size: 12px;
font-family: Verdana, Arial, Helvetica, sans-serif;
}
-->
</style>  

  </head>
  <body>
  <br/>
  <br/>

  <h1 class="style1"> Access Denied </h1>
  <p class="style3">Your user ID or password is incorrect, or you are not a
 registered user on this site. To try logging in again, click
 <a href="<?=$_SERVER['PHP_SELF']?>">here</a>. To access, please contact our Admin     !</a>.</p>
  </body>
  </html>
  <?php
  exit;
}

$username = mysql_result($result,0,'fullname');
$_SESSION['user'] = mysql_result($result,0,'userid');
$_SESSION['email'] = mysql_result($result,0,'email');
$_SESSION['notes'] = mysql_result($result,0,'notes');

?>

2 个答案:

答案 0 :(得分:0)

首先,为什么要在会话变量中存储密码?

其次,你的代码假设会话​​变量'uid'和'pwd'将存在,如果POST变种'uid'和'pwd'没有,所以你需要确保在你之前存在或存在允许您的脚本继续。这必须在session_start()函数之后完成:

<?php // accesscontrol.php
include_once 'common.php';
include_once 'db.php';

session_start();

if(
      (!isset($_SESSION['uid']) || !isset($_SESSION['pwd'])) &&
      (!isset($_POST['uid']) || !isset($_POST['pwd']))
{
     //Redirect or throw exception or whatever
}

$uid = isset($_POST['uid']) ? $_POST['uid'] : $_SESSION['uid'];
$pwd = isset($_POST['pwd']) ? $_POST['pwd'] : $_SESSION['pwd'];

答案 1 :(得分:0)

你不应该:

  • 在数据库中保留明文密码
  • 使用mysql扩展名
  • 2012年在没有框架的情况下发展

问题的关键在于:PHP如何判断请求来自哪个用户?上次我检查时使用了作为GET参数发送的令牌或者在HTTP请求头部分中使用了cookie(我认为它被称为PHPSESSID)。

显然,为了保证没有人窃取会话,必须通过安全通道交换身份令牌,即一旦用户登录,您必须生成会话ID并禁用端口80上的普通HTTP套接字。需要登录用户的脚本必须保存在一个单独的主机中,该主机只允许在端口443上使用HTTPS。

会话ID将从登录脚本中分配,并保存在user表的列中。 BTW,常规应用程序使用单独的表将会话关联到用户,但由于每个用户需要一个客户端,user表中的列就足够了。

因此,当请求附带会话令牌时,如果令牌仍然有效,则授权逻辑将检查用户表。它应该使用令牌来验证用户,因此如果请求中不包含一个令牌,或者在数据库中找不到令牌,则发出403 FORBIDDEN并建议登录URL Location标题 - 如果代理不自动跟随重定向,您还可以编写带有<a>链接的HTML页面。

登录脚本将提交使用令牌更新列,具体取决于您要执行的操作:使旧会话无效或阻止创建新会话,直到用户明确注销另一个客户端(后者导致故障)如果用户无法访问之前登录过的旧计算机,可能是因为如果关闭了移动设备,或者因为它位于不同的建筑物中,那么