Yii文件管理系统需四层权限控制:角色、动作、文件类型、存储路径。先建RBAC基础,定义细粒度权限并绑定角色;上传前校验权限,模型规则结合上下文;路径按角色隔离并禁用原始文件名;下载预览均经控制器鉴权中转。

Yii做文件管理系统,权限管控不能只靠“谁登录了谁就能传”,得把用户角色、操作动作、文件类型、存储路径
四层控制拧在一起。下面讲清楚怎么落地,不绕弯、不堆概念。一、RBAC权限体系必须先搭稳
没角色权限基础,后续所有控制都是空中楼阁。
- 用
DbManager建表:在终端执行yii migrate --migrationPath=@yii/rbac/migrations,确保生成auth_item、auth_assignment等四张表 - 定义最小粒度权限项:比如
upload-avatar(头像)、upload-report(报表)、delete-own-file(删自己传的)——每个权限名对应一个具体动作+资源范围 - 创建角色并分配:管理员可拥有全部权限;普通用户只赋予
upload-avatar和view-own-files;审核员额外加approve-report - 给用户绑定角色:用
$auth->assign($role, $userId),别依赖后台界面点选,关键账号建议代码固化
二、上传模型里嵌权限校验逻辑
权限检查必须在模型验证之前完成,否则攻击者可能绕过前端限制直接提交恶意文件。
- 在控制器 action 开头就判断:
if (!Yii::$app->user->can('upload-report')) { throw new ForbiddenHttpException('无权上传报表'); } - 模型 rules 中不只写扩展名,还要绑定权限上下文:
['file', 'file', 'extensions' => 'pdf,xlsx', 'maxSize' => 10485760](10MB),大小限制要早于 PHP 层拦截,避免浪费资源 - 对敏感操作(如删除、下载)也做同样前置校验,例如下载前查
Yii::$app->user->can('download-file', ['fileId' => $id]),配合 Rule 类做动态判断
三、文件存储路径按权限隔离
同一套上传代码,不同角色上传的文件必须落到不同目录,物理隔离是最硬的防线。
- 用 Yii 别名统一管理路径,例如在
common/config/bootstrap.php中设:Yii::setAlias('uploads', dirname(dirname(__DIR__)) . '/frontend/web/uploads'); - 根据用户角色或权限动态拼路径:
$dir = Yii::getAlias('@uploads') . '/' . ($user->isSuperAdmin ? 'admin/' : 'user/' . $user->id . '/'); - 禁止使用原始文件名:
$safeName = Yii::$app->security->generateRandomString(16) . '.' . $file->extension;,彻底杜绝../../etc/passwd类路径遍历 - 上传目录权限设为
chown -R www:www uploads/+chmod -R g+rw,g+x uploads/,严禁777
四、文件访问与下载加二次鉴权
上传完不是终点,别人能不能看到、下载、预览,还得再卡一道。
- 不要让文件直接放在
web/uploads/下被浏览器直连;要么移出 webroot(如存到@runtime/uploads),要么用控制器中转 - 提供下载接口,例如
actionDownload($id),先查文件归属和用户权限:$file = File::findOne($id); if (!$file || !Yii::$app->user->can('view-file', ['file' => $file])) { throw new ForbiddenHttpException(); } - 返回文件时用
return Yii::$app->response->sendFile($filePath, $file->original_name);,不暴露真实路径 - 对图片等需预览的资源,走
actionPreview($id),同样鉴权后输出二进制流,并设置Content-Type


















