CodeIgniter3中PDF文件存储位置及登录用户访问权限方案咨询
CodeIgniter 3 PDF存储与权限控制最优方案
刚好之前在CodeIgniter 3里折腾过类似的需求,给你一套经过验证的靠谱方案,分存储位置和权限控制两部分讲清楚:
一、存储位置:放在Web根目录之外
绝对不要把PDF放在Web根目录(比如public_html或者项目里index.php所在的文件夹),不然用户只要知道文件名就能直接访问。最优选择是Web根目录的上级目录,举个典型的项目结构:
/var/www/ ├─ my_ci_project/ # Web根目录,包含index.php └─ ci_pdfs/ # 专门存PDF的目录,Web服务器不直接映射
这么做的核心好处:
- 彻底避免HTTP直接访问,哪怕服务器配置出错也不会泄露文件
- 完全脱离Web服务的直接管控,安全性拉满
然后在CodeIgniter里配置这个路径:打开application/config/config.php,添加全局常量方便后续调用:
define('PDF_STORAGE_PATH', '/var/www/ci_pdfs'); // 替换成你实际的路径
二、权限控制:通过控制器中转访问
核心思路是不让用户直接接触文件,所有PDF请求都经过CodeIgniter控制器验证权限,具体步骤如下:
1. 创建权限验证控制器
新建application/controllers/PdfController.php,负责处理所有PDF的访问请求:
<?php defined('BASEPATH') OR exit('No direct script access allowed'); class PdfController extends CI_Controller { public function __construct() { parent::__construct(); // 确保session库已加载(如果没在autoload里配置的话) $this->load->library('session'); } public function view($file_id) { // 第一步:检查用户是否登录 if (!$this->session->userdata('logged_in')) { redirect('auth/login'); // 跳转到你的登录页面 return; } // 第二步:从数据库获取PDF关联记录(建议把PDF信息存在数据库) $this->load->model('Pdf_model'); $pdf_record = $this->Pdf_model->get_pdf_by_id($file_id); // 第三步:验证PDF是否属于当前用户(防止越权访问) if (!$pdf_record || $pdf_record['user_id'] != $this->session->userdata('user_id')) { show_404(); // 返回404,不让用户知道文件存在 return; } $pdf_path = PDF_STORAGE_PATH . '/' . $pdf_record['filename']; // 第四步:安全校验,防止路径遍历攻击(比如../../etc/passwd) if (!file_exists($pdf_path) || realpath($pdf_path) !== realpath(PDF_STORAGE_PATH . '/' . basename($pdf_record['filename']))) { show_404(); return; } // 第五步:输出PDF给用户(inline是在线预览,attachment是强制下载) header('Content-Type: application/pdf'); header('Content-Disposition: inline; filename="' . $pdf_record['filename'] . '"'); header('Content-Length: ' . filesize($pdf_path)); readfile($pdf_path); exit; } }
2. 配套数据库模型
新建application/models/Pdf_model.php,用来操作PDF的关联记录:
<?php class Pdf_model extends CI_Model { public function get_pdf_by_id($file_id) { // 假设你有个`pdfs`表,字段包括id, user_id, filename, created_at return $this->db->get_where('pdfs', ['id' => $file_id])->row_array(); } }
3. 生成PDF时的存储逻辑
当你用TCPDF/dompdf生成PDF后,保存到指定目录并记录到数据库:
// 示例:用TCPDF生成PDF $this->load->library('tcpdf'); $pdf = new TCPDF(); // ... 这里写你的PDF内容生成代码 ... // 生成唯一文件名,避免重名和恶意覆盖 $unique_filename = 'user_' . $this->session->userdata('user_id') . '_' . time() . '_' . uniqid() . '.pdf'; // 保存到外部目录 $pdf->output(PDF_STORAGE_PATH . '/' . $unique_filename, 'F'); // 记录到数据库,方便后续关联用户和权限验证 $this->db->insert('pdfs', [ 'user_id' => $this->session->userdata('user_id'), 'filename' => $unique_filename, 'created_at' => date('Y-m-d H:i:s') ]);
三、额外安全细节
- 设置存储目录权限:给
ci_pdfs目录设置chmod 700,确保只有Web服务器用户(比如www-data)能读写,其他用户无法访问 - 验证文件类型:可以用
finfo_file检查文件实际是PDF,防止恶意文件混入 - 限制请求频率:可以加个简单的限流逻辑,防止恶意请求刷接口
内容的提问来源于stack exchange,提问作者Tikky
相关产品推荐
相关产品推荐

