首页主机资讯Linux中ThinkPHP权限控制

Linux中ThinkPHP权限控制

时间2025-12-03 00:45:05发布访客分类主机资讯浏览445
导读:Linux下 ThinkPHP 权限控制实践 一 概念与总体架构 在 Linux 部署 ThinkPHP,权限控制通常包含两类: 系统层面:文件和目录的访问权限与属主/属组,确保 Web 服务进程对缓存、日志等可写目录具备写入能力,同时...

Linux下 ThinkPHP 权限控制实践

一 概念与总体架构

  • 在 Linux 部署 ThinkPHP,权限控制通常包含两类:
    • 系统层面:文件和目录的访问权限属主/属组,确保 Web 服务进程对缓存、日志等可写目录具备写入能力,同时避免对敏感目录的非法访问。
    • 应用层面:基于 RBAC(基于角色的访问控制)用户-角色-权限模型与中间件校验,控制控制器/方法的访问。
  • 推荐的数据表结构:users / roles / permissions / user_roles / role_permissions,通过中间件在请求进入控制器前进行鉴权与放行。

二 系统层面目录权限与安全防护

  • 基本思路
    • 将站点目录的所有者设为部署用户(如:demo),所属组设为 Web 服务运行用户(如 www-dataapache),再按“目录 750、文件 640”收紧权限,仅对需要写入的目录单独放宽。
    • runtime 等需要写入的目录,递归设置为 770,保证进程可写;同时禁止通过浏览器直接访问敏感目录与 PHP 文件。
  • 示例命令(以 Ubuntu/Apache 为例,Web 运行用户为 www-data,站点目录为 /var/www/html/demo
    # 1) 调整属主/属组
    chown -R demo:www-data /var/www/html/demo
    
    # 2) 目录 750,文件 640
    find /var/www/html/demo -type d -exec chmod 750 {
    }
         \;
    
    find /var/www/html/demo -not -type d -exec chmod 640 {
    }
         \;
    
    
    # 3) 对需要写入的目录(如 runtime、上传目录)放宽到 770
    find /var/www/html/demo -name "runtime" -type d -exec chmod -R 770 {
    }
         \;
    
    # 如有上传目录:find /var/www/html/demo -name "upload" -type d -exec chmod -R 770 {
    }
         \;
        
    
  • 禁止访问敏感目录(Apache)
    • runtime/.htaccess 中加入:
      Order Allow,Deny
      Deny from all
      
    • 或在项目根目录的 .htaccess 中限制访问 config/runtime/ 下的 .php 文件:
      <
          FilesMatch "\.php$">
          
          Order deny,allow
          Deny from all
      <
          /FilesMatch>
          
      <
          FilesMatch "^(.*)/config/.*\.php$">
          
          Order deny,allow
          Deny from all
      <
          /FilesMatch>
          
      <
          FilesMatch "^(.*)/runtime/.*\.php$">
          
          Order deny,allow
          Deny from all
      <
          /FilesMatch>
          
      
  • 安全提醒
    • 避免使用 chmod 777 -R,这会放宽所有用户权限,存在重大安全风险。
    • 若使用 Nginx+PHP-FPM,需将 PHP-FPM 运行用户/组与目录属组保持一致(如同为 www-data),否则会出现写入失败。

三 应用层面 RBAC 与中间件实现

  • 数据表设计(示例)
    CREATE TABLE `users` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(50) NOT NULL,
      `password` varchar(255) NOT NULL,
      PRIMARY KEY (`id`)
    );
        
    
    CREATE TABLE `roles` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(50) NOT NULL,
      PRIMARY KEY (`id`)
    );
        
    
    CREATE TABLE `permissions` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(50) NOT NULL,
      `action` varchar(100) NOT NULL, -- 如:admin/user/list
      PRIMARY KEY (`id`)
    );
        
    
    CREATE TABLE `user_roles` (
      `user_id` int(11) NOT NULL,
      `role_id` int(11) NOT NULL,
      PRIMARY KEY (`user_id`,`role_id`)
    );
        
    
    CREATE TABLE `role_permissions` (
      `role_id` int(11) NOT NULL,
      `permission_id` int(11) NOT NULL,
      PRIMARY KEY (`role_id`,`permission_id`)
    );
        
    
  • 中间件示例(认证 + 权限校验)
    // app/middleware/Auth.php
    namespace app\middleware;
        
    
    use think\Request;
        
    use think\facade\Session;
        
    use app\model\User;
        
    use app\model\Role;
        
    use app\model\Permission;
    
    
    class Auth
    {
        
        // 无需校验的白名单(如登录、验证码)
        protected $whiteList = ['login', 'captcha'];
    
    
        public function handle(Request $request, \Closure $next)
        {
        
            $controllerAction = strtolower($request->
        controller() . '/' . $request->
        action());
        
            if (in_array($controllerAction, $this->
    whiteList, true)) {
        
                return $next($request);
    
            }
        
    
            $userId = Session::get('user_id');
    
            if (!$userId) {
        
                return redirect('/login');
    
            }
        
    
            $user = User::with(['roles.permissions'])->
        find($userId);
    
            if (!$user) {
        
                Session::delete('user_id');
        
                return redirect('/login');
    
            }
        
    
            // 将用户与权限注入到请求,便于控制器/视图使用
            $request->
        user = $user;
        
            $perms = [];
        
            foreach ($user->
    roles as $role) {
        
                foreach ($role->
    permissions as $perm) {
        
                    $perms[$perm->
        action] = true;
    
                }
    
            }
        
            $request->
        userPerms = $perms;
    
    
            // 校验当前请求是否在用户权限中
            if (!isset($perms[$controllerAction])) {
        
                return json(['code' =>
         403, 'msg' =>
         '无权限'], 403);
    
            }
        
    
            return $next($request);
    
        }
    
    }
    
    
  • 在路由或控制器中应用中间件
    // 全局应用(示例)
    // 或者在需要保护的路由组/控制器构造中绑定中间件
    
  • 登录示例(简化)
    // app/controller/Index.php
    public function login()
    {
        
        $username = $this->
        request->
        param('username');
        
        $password = $this->
        request->
        param('password');
        
    
        $user = User::where('username', $username)->
        find();
        
        if ($user &
        &
         password_verify($password, $user->
    password)) {
        
            Session::set('user_id', $user->
        id);
        
            return json(['status' =>
         'success', 'message' =>
         '登录成功']);
    
        }
        
        return json(['status' =>
         'error', 'message' =>
         '用户名或密码错误']);
    
    }
        
    
  • 扩展
    • 可按需引入 ABAC(基于属性:时间、IP、设备等)或细粒度到“按钮/接口”的权限判断。

四 常见问题与排查

  • 出现“日志/缓存写入失败”
    • 检查 runtime 目录及其子目录对 Web 运行用户是否可写(属主/属组是否正确,权限是否 ≥ 770)。
    • 若使用 Nginx+PHP-FPM,确认 PHP-FPM 的 user/group 与目录属组一致。
  • 浏览器能直接访问 runtime 下的敏感文件
    • runtime/.htaccess 中写入“Deny from all”,或在根目录 .htaccess 限制 config/runtime/.php 访问。
  • 使用 chmod 777 后仍有写入问题
    • 多数为 SELinuxopen_basedir 限制,检查并调整策略或关闭相关限制(生产环境不建议直接关闭,应精细化策略)。
  • 部署脚本批量设置权限
    • 可编写脚本对多个项目统一设置 Runtime 目录权限,但务必避免对整站使用 777

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: Linux中ThinkPHP权限控制
本文地址: https://pptw.com/jishu/761888.html
ubuntu swap文件系统选择 ThinkPHP扩展功能探索

游客 回复需填写必要信息