PHP费用审批系统多角色授权异常问题排查
问题排查与修复
核心错误原因
你收到“Unauthorized access”的直接原因是权限判断逻辑错误:
原代码中使用in_array($user_type, $allowedRoles)进行权限校验,但$user_type是逗号分隔的字符串(比如'ccapprover, observer'),而$allowedRoles是单个角色组成的数组,这个判断永远会返回false,直接触发未授权提示。
修复方案
需要调整权限校验的顺序和逻辑,先拆分用户角色再进行校验,同时处理角色字符串的空格问题(避免因数据库中角色格式不一致导致的拆分错误):
修改后的process_approval.php关键部分代码:
include 'session.php'; include 'config.php'; // 确保$email从session中获取(原代码未显式定义,需补充) $email = $_SESSION['email'] ?? ''; if ($_SERVER["REQUEST_METHOD"] == "POST") { $reportId = $_POST['report_id']; $approval = $_POST['approval']; $allowedRoles = ['manager', 'finance', 'ccapprover', 'observer']; // 1. 拆分用户角色并清理每个角色的空格(兼容带/不带空格的逗号分隔格式) $userRoles = array_map('trim', explode(',', $user_type)); // 2. 校验用户是否拥有至少一个允许的角色 $validRoles = array_intersect($userRoles, $allowedRoles); if (!empty($validRoles)) { foreach ($validRoles as $approvedRole) { $approverColumn = ''; $statusColumn = ''; $dateColumn = ''; switch ($approvedRole) { case 'manager': $approverColumn = 'mng_approver'; $statusColumn = 'mng_approver_status'; $dateColumn = 'mng_approval_date'; break; case 'finance': $approverColumn = 'finance_approval'; $statusColumn = 'finance_approval_status'; $dateColumn = 'finance_approval_date'; break; case 'ccapprover': $approverColumn = 'cc_approver'; $statusColumn = 'cc_approver_status'; $dateColumn = 'cc_approval_date'; break; case 'observer': $approverColumn = 'observer'; $statusColumn = 'observer_status'; $dateColumn = 'observer_approval_date'; break; } if (!empty($approverColumn)) { $updateQuery = "UPDATE expenses SET $approverColumn = :email, $statusColumn = :status, $dateColumn = NOW() WHERE id = :report_id"; try { $stmt = $pdo->prepare($updateQuery); $stmt->bindParam(':email', $email); $stmt->bindParam(':status', $approval); $stmt->bindParam(':report_id', $reportId); $stmt->execute(); echo "Approval/Rejection recorded successfully for role: $approvedRole<br>"; } catch (PDOException $e) { echo "Error recording approval/rejection: " . $e->getMessage(); } } else { echo "Invalid approver role: $approvedRole<br>"; } } } else { echo "Unauthorized access."; } } else { echo "No POST data received."; }
关键修改点说明
- 角色拆分与清理:使用
array_map('trim', explode(',', $user_type)),先按逗号拆分,再去除每个角色前后的空格,兼容数据库中'ccapprover,observer'或'ccapprover, observer'两种格式。 - 权限校验逻辑:用
array_intersect($userRoles, $allowedRoles)获取用户拥有的合法角色集合,只要集合不为空,就允许执行审批操作。 - 循环范围调整:直接遍历用户的合法角色集合,避免处理无效角色。
- 补充$email定义:原代码中使用了
$email但未显式从session获取,补充$email = $_SESSION['email'] ?? ''确保变量存在。
内容的提问来源于stack exchange,提问作者Qbasix
相关产品推荐
相关产品推荐

