首页 > 解决方案 > 如何在某些页面上获得管理员访问权限

问题描述

我创建了一个具有基本注册和登录系统的网站,我的页面只希望管理员访问。

我的帐户数据库有一个角色列,其中 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; 
} 
?>

这是我在页面中使用的代码,

我遇到的问题是我登录的人并不重要,因为它总是重定向,而我希望管理员可以访问该页面,而不是用户。

标签: php

解决方案


首先,您需要更改查询以返回该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 用户仅对他们需要的数据具有有限的权限

来自马丁的评论。


推荐阅读