php - 如何在某些页面上获得管理员访问权限
问题描述
我创建了一个具有基本注册和登录系统的网站,我的页面只希望管理员访问。
我的帐户数据库有一个角色列,其中 1 个用户分配为管理员,另一个分配为用户
认证.PHP
<?php
session_start();
// Change this to your connection info.
$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'root';
$DATABASE_PASS = '';
$DATABASE_NAME = 'feedbackdb';
// Try and connect using the info above.
$con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
if ( mysqli_connect_errno() ) {
// If there is an error with the connection, stop the script and display the error.
exit('Failed to connect to MySQL: ' . mysqli_connect_error());
}
// Now we check if the data from the login form was submitted, isset() will check if the data exists.
if ( !isset($_POST['username'], $_POST['password']) ) {
// Could not get the data that should have been sent.
exit('Please fill both the username and password fields!');
}
// Prepare our SQL, preparing the SQL statement will prevent SQL injection.
if ($stmt = $con->prepare('SELECT id, password FROM accounts WHERE username = ?')) {
// Bind parameters (s = string, i = int, b = blob, etc), in our case the username is a string so we use "s"
$stmt->bind_param('s', $_POST['username']);
$stmt->execute();
// Store the result so we can check if the account exists in the database.
$stmt->store_result();
if ($stmt->num_rows > 0) {
$stmt->bind_result($id, $password);
$stmt->fetch();
// Account exists, now we verify the password.
// Note: remember to use password_hash in your registration file to store the hashed passwords.
if (password_verify($_POST['password'], $password)) {
// Verification success! User has loggedin!
// Create sessions so we know the user is logged in, they basically act like cookies but remember the data on the server.
session_regenerate_id();
$_SESSION['loggedin'] = TRUE;
$_SESSION['name'] = $_POST['username'];
$_SESSION['id'] = $id;
$_SESSION['admin'] = true/false;
header('location: home.php');
} else {
echo 'Incorrect password!';
}
} else {
echo 'Incorrect username!';
}
$stmt->close();
}
?>
我用来检查的:
<?php
session_start();
if(isset($_SESSION['admin'], $_SESSION['admin'])){
header('Location: index.php');
exit;
}
?>
这是我在页面中使用的代码,
我遇到的问题是我登录的人并不重要,因为它总是重定向,而我希望管理员可以访问该页面,而不是用户。
解决方案
首先,您需要更改查询以返回该role
列。
if ($stmt = $con->prepare('SELECT id, password, role FROM accounts WHERE username = ?'))
接下来,您需要以与您相同的方式绑定该值,$id
并且$password
.
$stmt->bind_result($id, $password, $role);
接下来,在password_verify()
您分配其他$_SESSION
变量的块内,设置一个role
变量。
$_SESSION['loggedin'] = TRUE;
$_SESSION['name'] = $_POST['username'];
$_SESSION['id'] = $id;
$_SESSION['role'] = $role;
现在,在您想要的任何页面上,您都可以阻止任何非管理员的访问。
if(empty($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
//block user access
die("You do not have permission to view this page.");
}
如果您想在页面上显示仅对管理员可见的内容而不完全阻止所有用户访问该页面,您可以这样做
if(!empty($_SESSION['role']) && $_SESSION['role'] == 'admin') {
echo "Only admins can see this text.";
}
变量清理
user
我建议您创建一个包含您可能需要的数据数组的单个会话变量,而不是创建多个不同的会话变量。我推荐这个,因为它更干净,更容易管理,并且更容易在你的代码中使用。
基本上,将所有$_SESSION
变量声明替换为:
$_SESSION['user'] = [
'loggedin' => true,
'name' => $_POST['username'],
'id' => $id,
'role' => $role
];
然后,要检查用户是否是管理员,您可以执行以下操作:
if(empty($_SESSION['user']) || $_SESSION['user']['role'] !== 'admin') {
//block user access
die("You do not have permission to view this page.");
}
并且只为管理员显示一些东西而不完全阻止页面中的所有用户:
if(!empty($_SESSION['user']) && $_SESSION['user']['role'] == 'admin') {
echo "Only admins can see this text.";
}
注意:使用 MySQL Root 用户访问网站数据库是非常不明智和不安全的。不要这样做。使特定的 MySQL 用户仅对他们需要的数据具有有限的权限
来自马丁的评论。
推荐阅读
- algorithm - 求一棵树的最小重量
- javascript - Qt 资源加载空的 .js 文件
- xaml - UWP XAML 在数据模板之外添加数据绑定
- html - CSS变换比例忽略z-index和渐变
- python - 如何在使用 bazel 构建的项目中使用 vscode python 调试器?
- python - 如何分解用逗号分隔的数字并使用熊猫将分隔的数字带到下一行?
- google-colaboratory - 安装meshroom时google colab中的符号链接错误
- json - 如何使用 laravel 更新 postgresql 数据库中的 json 数据?
- c++ - 错误在哪里?C++ 中的密码输入代码
- ruby-on-rails - Rails 表单提交空白