You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CodeIgniter中保护public文件夹内文件仅允许已登录用户访问

CodeIgniter public目录指定资源仅登录用户访问配置方案

核心原因:默认情况下Nginx/Apache会直接返回public目录下的静态文件,不会经过CodeIgniter的权限校验逻辑,所以需要调整配置让目标路径的请求走框架的权限校验流程。

方案1:保留目录位置,通过重写规则接入框架校验

步骤1:配置Web服务器重写规则

根据你使用的Web服务器选择对应配置:

  • Nginx配置:在站点配置中添加如下规则,注意要放置在通用静态资源匹配规则之前,避免被覆盖
location ~ ^/(logs|code)/ {
    try_files $uri $uri/ /index.php?$query_string;
}
  • Apache配置:修改public目录下的.htaccess文件,添加如下规则
RewriteEngine On
RewriteRule ^(logs|code)/.*$ index.php [L]

步骤2:创建资源鉴权控制器

新建application/controllers/ProtectedAsset.php控制器,实现登录校验、路径安全校验和文件返回逻辑:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class ProtectedAsset extends CI_Controller {
    public function serve($type, $path) {
        // 替换为你项目自身的登录状态校验逻辑
        if (!$this->session->userdata('is_login')) {
            show_error('无权访问', 403);
        }

        // 拼接真实文件路径,做路径安全校验防止路径遍历漏洞
        $public_root = FCPATH;
        $full_path = realpath($public_root . $type . '/' . $path);
        $allowed_paths = [
            realpath($public_root . 'logs/'),
            realpath($public_root . 'code/')
        ];

        // 校验路径合法性
        $valid = false;
        foreach ($allowed_paths as $allow_dir) {
            if (strpos($full_path, $allow_dir) === 0) {
                $valid = true;
                break;
            }
        }
        if (!$valid || !file_exists($full_path) || is_dir($full_path)) {
            show_404();
        }

        // 返回文件内容,设置正确的响应头
        $mime = get_mime_by_extension($full_path);
        header('Content-Type: ' . $mime);
        header('Content-Length: ' . filesize($full_path));
        // 可选添加缓存头提升性能
        // header('Cache-Control: public, max-age=86400');
        readfile($full_path);
        exit;
    }
}

步骤3:配置路由转发规则

打开application/config/routes.php,添加路由将目标路径请求转发到鉴权控制器:

$route['logs/(:any)'] = 'ProtectedAsset/serve/logs/$1';
$route['code/(:any)'] = 'ProtectedAsset/serve/code/$1';

方案2:移动敏感文件到非public目录(安全性更高)

从根源避免Web服务器直接泄露文件的风险,操作逻辑和方案1基本一致:

  1. 将logs和code目录整体移动到和public同级的目录,不再放入public内
  2. 控制器中拼接文件路径时,将FCPATH替换为APPPATH对应的上级目录路径即可
  3. 无需额外配置Web服务器重写规则,因为文件本身不在公开目录,所有访问必然走框架逻辑

注意事项

  • 必须保留路径安全校验逻辑,避免攻击者构造../类路径遍历请求,窃取项目敏感配置文件
  • 若访问的文件体积较大,可按需添加缓存头、断点续传支持,降低PHP处理的性能开销
  • 登录校验逻辑需和项目现有认证体系对齐,若使用第三方认证库(如ion_auth),替换为对应库的校验方法即可

内容的提问来源于stack exchange,提问作者Rovin Patwal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 17:15:08