我目前正在学习PHP和MySQL,而且我一直在使用一个基本的(尽管是旧的)登录脚本教程 - 我遇到过各种折旧函数等等,我正在努力改进这个脚本。
我想为我的脚本添加不同的访问级别,例如管理员和用户。我在“用户”表格中添加了一行名为“access”的行,用户访问权限为“1”,管理员访问权限为“9”。
经过一些初步研究后,似乎我需要能够将用户访问级别存储在会话变量中 - 这是正确的方法吗?如果是这样,当用户登录时,我最初将如何检索?
一旦访问级别存储在会话变量中,我将如何限制对页面的访问 - 可能使用标题重定向?
这是我正在使用的函数.php
function checkLogin()
{
/* Check if user has been remembered */
if(isset($_COOKIE['cookname']) && isset($_COOKIE['cookpass'])){
$_SESSION['username'] = $_COOKIE['cookname'];
$_SESSION['password'] = $_COOKIE['cookpass'];
}
/* Username and password have been set */
if(isset($_SESSION['username']) && isset($_SESSION['password']))
{
/* Confirm that username and password are valid */
if(confirmUser($_SESSION['username'], $_SESSION['password']) != 0)
{
/* Variables are incorrect, user not logged in */
unset($_SESSION['username']);
unset($_SESSION['password']);
return false;
}
return true;
}
/* User not logged in */
else
{
return false;
}
}
来自login.php
if(isset($_POST['sublogin'])){
/* Check that all fields were typed in */
if(!$_POST['user'] || !$_POST['pass']){
$errors .= "You didn't fill in a required field.<br/>\n";
}
else{
/* Once all fields are entered - perform form validation */
/* Checks that username is in database and password is correct */
$md5pass = md5($_POST['pass']);
$result = confirmUser($_POST['user'], $md5pass);
/* Check error codes */
if($result == 1){
$user_errors .= "That username doesn't exist in our database.<br/>\n";
}
else if($result == 2){
$pass_errors .= "Incorrect password, please try again.<br/>\n";
}
/* Username and password correct, register session variables */
if (empty($errors) && empty($user_errors) && empty($pass_errors)){
$_POST['user'] = mysql_real_escape_string($_POST['user']);
$_SESSION['username'] = $_POST['user'];
$_SESSION['password'] = $md5pass;
/* Quick self-redirect to avoid resending data on refresh */
echo "<META HTTP-EQUIV='refresh' CONTENT='0;URL=index.php'>";
}
/**
* This is the cool part: the user has requested that we remember that
* and one to hold his md5 encrypted password. We set them both to
* he's logged in, so we set two cookies. One to hold his username,
* expire in 100 days. Now, next time he comes to our site, we will
* log him in automatically.
*/
if(isset($_POST['remember'])){
setcookie("cookname", $_SESSION['username'], time()+60*60*24*100, "/");
setcookie("cookpass", $_SESSION['password'], time()+60*60*24*100, "/");
}
//return;
}
}
任何帮助都会非常感激,因为我已经坚持了几天,谢谢。
答案 0 :(得分:1)
为用户表中的不同类型的用户分配不同的角色ID。
有一个上下文表,它将存储不同文件路径的信息(最好是文件夹中所需层次结构的最顶层)。
并且包含角色和不同文件路径之间的映射的表(即允许哪种类型的用户访问哪条路径)
现在位于受限文件的顶部,有一个util方法,它将接收__FILE__路径和角色ID,并告诉用户是否具有访问权限,从而采取相关措施。所以你只需要在会话变量中存储角色id。
答案 1 :(得分:1)
因此,前者假设您正在检查PHP中角色的限制资源,而不是来自数据库。这可以很容易地改变,但我想我会让这个有点简单。
users
-------
id_user
identity
credential
role
... other fields
不要使用md5,它易于实现,并且易于克服。 sha只是一个更安全的小事,没有额外的工作。
$email_or_username = "francis@yaconiello.com";
$password = "PinkEleph4nt"; // not my real password for anything
$role = "admin";
$sql = sprintf("INSERT INTO users SET identity='%s', credential='%s', role='%s'",
mysql_real_escape_string($email_or_username),
mysql_real_escape_string(sha1($password)),
mysql_real_escape_string($role));
这是缩短的,我把查询放进去,但不是很多DB逻辑,把它写成需要的,阅读评论。
// VALIDATE THE EMAIL/USERNAME and PASSWORD
if($is_valid == TRUE)
{
$sql = sprintf("SELECT id_user FROM users WHERE identity='%s' AND credential='%s' LIMIT 1",
mysql_real_escape_string($email_or_username),
mysql_real_escape_string(sha1($password)));
// FETCH ROW save into $row
if(!empty($row))
{
// A user was fetched save it into the session
$_SESSION['id_user'] = $row['id_user'];
// SUCCESS
}
else
{
// FAILURE
}
}
<?php
function fetch_role()
{
$role = "guest";
if(isset($_SESSION['id_user']))
{
// User exists
$sql = sprintf("SELECT * FROM users WHERE id_user='%s' LIMIT 1",
mysql_real_escape_string($_SESSION['id_user']));
// RUN THE MYSQL QUERY TO FETCH THE USER, SAVE INTO $row
if(!empty($row))
{
$role = $user_row['role'];
}
}
return $role;
}
...
$role = fetch_role();
if($role == 'guest')
{
// SHOW GUEST CONTENT
}
elseif($role == 'member')
{
// SHOW OTHER CONTENT
}
elseif($role == 'admin')
{
// SHOW ADMIN CONTENT
}