我想在我的网站上建立和ENFORCE用户权限。
我有两个用户组:买家和商家。
例如,对于我有的买家(在/ login / dir下):
<form method="post" action="check_buyer.php" id="LoggingInBuyer">
<div style="width:265px;margin:0; padding:0; float:left;">
<label>Username:
<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:
<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目录
<?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>";
}
?>
问题是以buyer
身份登录后,我只能输入:login/merchant
即使会话$_SESSION['uUserType']
中的字段不断出现,也会将其带到那里重新验证为= 1
。
如何阻止用户只在网址中输入login/merchant
,他们可以访问该网址?
答案 0 :(得分:2)
首先,您无法阻止用户输入特定网址。将某些脚本或代码部分限制为特定用户的唯一方法是使用代码[或者,某些Apache设置]。
此代码错误,因为它(可能)是为了检查会话是否存在而编写的,但不检查它是否是买方会话:
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设计会更好。
答案 1 :(得分:1)
你有
吗?session_start();
if( 2!== $_SESSION['uUserType'])
{
///login/merchant content goes here (login form, whole page, etc.)
} else {
header("location: http://www.example.com/whatever/buyer_page.php");
//redirect to whatever page you want
//or instead of header you could do an
//echo "You're already logged in" or whatever message you want
}
在您的商家页面上? (您不希望买家能够访问的每个页面)
重要的是要注意在使用标题之前可能没有输出html(“位置....这包括标签之外的空格。所以确保在打开之前没有空格