php - 在登录系统 PHP 中实现用户帐户

标签 php mysql session authentication login-control

我想在我的网站上建立并强制执行用户权限。

我有两个用户组:买家和商家。

例如,对于我的买家(在/login/dir 下):

<form method="post" action="check_buyer.php" id="LoggingInBuyer">
    <div style="width:265px;margin:0; padding:0; float:left;">
        <label>Username:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
             <span><a href="#">Forgot Username?</span></a>
        </label>
        <br />
        <input id="UserReg" style="width:250px;" type="text" name="userName" tabindex="1" class="required" />
    </div>
    <div style="width:265px;margin:0; padding:0; float:right;">
        <label>Password:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        <span><a href="#">Forgot Password?</span></a></label>
        <br />
        <input id="UserReg" style="width:250px;" type="password"  name="userPass" tabindex="2" class="required" />
    </div>
    <div class="clearB"> </div>
    <input type="submit" style="width:100px; margin:10px 200px;" id="UserRegSubmit" name="submit" value="Login" tabindex="3" />
</form>

PHP 脚本 check_buyer.php:

<?php
session_start(); #recall session from index.php where user logged include()

function isLoggedIn()
{
    if(isset($_SESSION['valid']) && $_SESSION['valid'])
        header( 'Location: buyer/' ); # return true if sessions are made and login creds are valid
    echo "Invalid Username and/or Password";  
    return false;
}

require_once('../inc/db/dbc.php');

$connect = mysql_connect($h, $u, $p) or die ("Can't Connect to Database.");
mysql_select_db($db);

$LoginUserName = $_POST['userName'];
$LoginPassword = mysql_real_escape_string($_POST['userPass']);
//connect to the database here
$LoginUserName = mysql_real_escape_string($LoginUserName);
$query = "SELECT uID, uUPass, dynamSalt, uUserType FROM User WHERE uUName = '$LoginUserName';";

$result = mysql_query($query);
if(mysql_num_rows($result) < 1) //no such USER exists
{
    echo "Invalid Username and/or Password";
}
$ifUserExists = mysql_fetch_array($result, MYSQL_ASSOC);

function validateUser() {
    $_SESSION['valid'] = 1;
    $_SESSION['uID'] = $uID;
    $_SESSION['uUserType'] = 1; // 1 for buyer - 2 for merchant
}

$dynamSalt = $ifUserExists['dynamSalt'];  #get value of dynamSalt in query above
$SaltyPass = hash('sha512',$dynamSalt.$LoginPassword); #recreate originally created dynamic, unique pass

if($SaltyPass != $ifUserExists['uUPass']) # incorrect PASS
{
    echo "Invalid Username and/or Password";
}

else {
validateUser();
}
// If User *has not* logged in yet, keep on /login
if(!isLoggedIn())
{
    header('Location: index.php');
    die();
}
?>

如果输入了有效的用户..它将转到/login/buyer dir

<?php
session_start();
if($_SESSION['uUserType']!=1)
{ 
    echo 'the userid: ' . $userid . '<br>' . 'the type is ' . $userType . '<br>';
    die("You may not view this page. Access denied.");
}

function isLoggedIn()
{
    return (isset($_SESSION['valid']) && $_SESSION['valid']);
}

//if the user has not logged in
if(!isLoggedIn())
{
    header('Location: index.php');
    die();
}
?>

<?php 
    if($_SESSION['valid'] == 1){
        #echo "<a href='../logout.php'>Logout</a>";
        require_once('buyer_profile.php');
    }
    else{
        echo "<a href='../index.php'>Login</a>";
    }
?>

问题是,一旦以买家身份登录,我只需输入:login/merchant,它就会带我到那里,即使 session 中的字段$_SESSION['uUserType'] 不断重新验证为 = 1

如何阻止用户仅在网址中输入 login/merchant 并获得访问权限?

最佳答案

首先,您无法阻止用户输入某个 URL。将某些脚本或代码部分限制为某些用户的唯一方法是通过代码 [或者,好吧,某些 Apache 设置]。

这段代码是错误的,因为它(可能)是为了检查 session 是否存在而编写的,但它不检查它是否是买家 session :

function isLoggedIn()
{
    if(isset($_SESSION['valid']) && $_SESSION['valid'])
        header( 'Location: buyer/' ); # return true if sessions are made and login creds are valid
    echo "Invalid Username and/or Password";  
    return false;
}

您还需要检查$_SESSION['uUserType']

我将所有内容封装在一个类中:

class CUserRole {

  const USER_NO_ROLE  = 'user.noRole';
  const USER_BUYER    = 'user.buyer';
  const USER_MERCHANT = 'user.merchant';

  const PAGE_LOGIN    = 'index.php';


  static 
  public function getCurrentUserRole() {

    if ( ! isset( $_SESSION )) {
       return self::USER_NO_ROLE;
    }

    switch( $_SESSION['uUserType'] ) {
      case 1:
       return self::USER_BUYER;

      case 2:
       return self::USER_MERCHANT;

      default:
        die( 'Inconsistent/Invalid uUserType' );
    }

  }

  static 
  public function forwardIfNotRole( $aRole, $forwardAddress = self::PAGE_LOGIN ) {

    if ( $aRole != self::getCurrentUserRole() ) {

      header( 'Location: ' . forwardAddress );
      exit;

    }

  }

  static 
  public function evaluateCredentials( ) {

    // checks passed login parameters against the DB
    // and sets up the session with appropriate values

  }

}

如有必要,请在脚本开头添加此行:

CUserRole::forwardIfNotRole( CUserRole::USER_BUYER, 'some/where/address' );  

或者简单地转发到index.php:

CUserRole::forwardIfNotRole( CUserRole::USER_BUYER );  

该解决方案将角色管理的主要部分封装在一个单独的类中。

最后,我不明白为什么要这样设置:

$_SESSION['valid'] = 1;

使用静态方法是一个非常简单的解决方案,使用 singleton pattern设计会好得多。

关于php - 在登录系统 PHP 中实现用户帐户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8249490/

相关文章:

php - Nginx + php5-fpm 不显示 php 错误但 cli 显示错误

javascript - Express.js/React.js 页面刷新状态持久化

mysql - SQL 将结果限制为前 50%

node.js - 是否可以使用客户端呈现的应用程序和 session 进行身份验证?

javascript - 如何防止使用 php 或 javascript 在同一浏览器 session 中打开另一个选项卡?

php - 从 PHP Mysql 标签的逗号分隔值中搜索关键字

php - 在子文件夹中安装 Laravel

php - wordpress cron 作业是顺序执行还是并行执行?

c# - 如何将从 MySQL 数据库获取的单行存储在变量中?

python - mysql 6.3/python 3.5 中的 CREATE TABLE 语法错误