PHP如何实现用户权限管理_PHP实现用户权限管理方法【安全】

蓮花仙者

蓮花仙者

2026-04-17

805人浏览

原创

权限应存入$_session['permissions']索引数组并设更新时间戳,登录后通过users→user_roles→role_permissions→permissions四表关联查询加载,校验时严格匹配原子权限名,中间件统一拦截确保检查前置。

php如何实现用户权限管理_php实现用户权限管理方法【安全】

直接用 session 存权限数组最简单,但容易出安全问题——比如没校验用户身份就写入权限、没清理过期 session、或把权限名硬编码在前端控制里。

怎么设计数据库才不容易被绕过

别用单表存 user.permissions 字段(如 JSON 或逗号分隔),这种设计无法做外键约束,也难审计权限变更。必须拆成四张表:

  • users:只存身份信息,password 必须用 password_hash() 加密
  • roles:角色是逻辑分组,不是权限本身,比如 editoradmin
  • permissions:每条记录是一个原子操作,如 post:deleteuser:edit_own,命名要带模块前缀
  • role_permissionsuser_roles:两个关联表,确保多对多关系可查、可删、可审计

关键点:user_roles 表必须存在,不能靠 users.role_id 外键直连——一个用户可能有多个角色,比如既是 editor 又是 reviewer

登录后怎么安全加载权限到 session

session 里不能只存 $_SESSION['role'],得存具体权限标识集合。否则每次判断都要查库,而且容易漏掉角色继承或动态权限变更。

  • 登录成功后,立即用用户 ID 查 user_rolesrole_permissionspermissions.name,拿到完整权限数组
  • 存进 $_SESSION['permissions'],不是字符串拼接,而是 array_values() 去重后的索引数组
  • 加个时间戳 $_SESSION['permissions_updated_at'] = time(),后续可设 15 分钟自动刷新,防权限变更后 session 滞后
  • 务必在所有权限检查前调用 session_start(),且不能有任何输出(包括 UTF-8 BOM)

错误示范:$_SESSION['permissions'] = 'delete_user,edit_post' —— 这种字符串无法用 in_array() 安全判断,还容易被注入逗号绕过。

PHP 8.5.5
PHP 8.5.5

PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。

下载

checkPermission() 函数为什么总失效

常见失效原因不是逻辑错,而是上下文没对齐。这个函数必须满足三个前提:

  • 它只能读 $_SESSION['permissions'],绝不能自己再去查数据库(否则失去缓存意义,还可能因 session 未初始化而报错)
  • 传入的权限名必须和 permissions.name 完全一致,大小写敏感,不能带空格或斜杠(如 'post:delete ' 就会失败)
  • 必须在页面最开头调用,不能放在 HTML 输出之后,否则 header() 重定向会失败
  • 如果用在 AJAX 接口里,要额外检查 $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest',返回 JSON 错误而非跳转

示例正确写法:

function checkPermission($perm) {
    if (!isset($_SESSION['permissions']) || !is_array($_SESSION['permissions'])) {
        return false;
    }
    return in_array($perm, $_SESSION['permissions'], true);
}

if (!checkPermission('user:delete_own')) {
    http_response_code(403);
    echo json_encode(['error' => 'Forbidden']);
    exit;
}

为什么中间件比每个页面写 checkPermission() 更可靠

因为中间件天然卡在路由解析之后、控制器执行之前,能统一拦截所有请求路径,包括静态资源、API 接口、甚至未命名路由。而手写 checkPermission() 很容易漏掉某个 include 文件或 AJAX 入口。

  • 中间件里不要依赖 $_SERVER['REQUEST_URI'] 做字符串匹配(比如 strpos('/admin/', ...)),容易被 /admin/../etc/passwd 绕过
  • 应该从路由定义中提取权限标识,例如 Laravel 的 $route->action['permission'],或自定义路由注释解析
  • 中间件必须 throw Exception 或 exit,不能只 echo 提示——否则后续代码仍会执行
  • 测试时重点验证:未登录用户访问受控路由 → 302 跳转;已登录但无权限 → 403;权限刚被后台回收 → 下次请求即生效(靠 permissions_updated_at 控制)

最常被忽略的一点:权限检查必须在数据库查询之前完成。比如一个 delete_user.php?id=123 页面,不能先查出用户数据再判断权限,而应在读取 id 后立刻校验 user:delete_own,否则攻击者可能通过修改 id 参数触发越权读取。

php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2023.09.01

5480

6

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

3610

5

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

1786

5

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

2023.10.23

2273

4

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

2023.10.23

2808

6

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.03

1999

9

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.09

3052

8

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.13

2315

8

sprintf函数用法详解
sprintf函数用法详解

sprintf函数的用法:1、格式化字符串;2、指定输出宽度和精度;3、返回值。更多关于sprintf函数用法详解的内容,大家可以阅读下面的文章。

2023.11.27

10931

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
墨刀帮助中心
墨刀帮助中心

共0课时 | 0人学习

MyEclipse学习中心
MyEclipse学习中心

共0课时 | 0人学习

Apache Subversion 官方手册
Apache Subversion 官方手册

共0课时 | 0人学习