如何通过Nginx结合CodeIgniter4为特定用户提供静态文件
解决Nginx结合CodeIgniter4提供用户专属静态文件的权限控制方案
以下是几个实用方案,既能让Nginx直接加速静态文件传输,又能依托CI4的登录体系完成权限校验:
方案一:FastCGI授权(推荐,无需额外Nginx模块)
利用Nginx的auth_request指令,让Nginx先请求CI4的授权接口验证用户权限,通过后再直接返回文件。
1. 编写CI4授权接口
在CI4中创建AuthController控制器,新增权限校验方法:
<?php namespace App\Controllers; use CodeIgniter\Controller; class AuthController extends Controller { public function checkAccess() { // 初始化会话,获取当前登录用户ID $session = session(); $currentUser = $session->get('user_id'); // 获取Nginx传递的目标文件路径 $targetPath = $_SERVER['HTTP_X_TARGET_PATH'] ?? ''; // 从路径中提取用户目录(如从/files/user1/img/foo.jpg中拿到user1) preg_match('#^/files/([^/]+)/#', $targetPath, $matches); $targetUser = $matches[1] ?? ''; // 权限校验:当前用户匹配目标目录+文件真实存在 if ($currentUser === $targetUser && file_exists(FCPATH . $targetPath)) { http_response_code(200); exit; } // 权限不足或文件不存在 http_response_code(403); exit; } }
2. 配置Nginx
修改站点配置,添加/files/路径的拦截规则:
server { # 原有配置... # 拦截用户专属文件请求 location ^~ /files/ { # 检查是否携带CI4会话Cookie(默认ci_session,可根据CI4配置调整) if ($http_cookie !~* "ci_session=") { return 403; } # 将目标路径通过HTTP头传给CI4授权接口 set $target_path $request_uri; proxy_set_header X-Target-Path $target_path; # 请求CI4授权接口做校验 auth_request /auth/check-access; # 校验通过后直接返回文件 root /path/to/your/project; # 项目根目录,确保/files在该路径下 try_files $uri =404; } # 授权接口的FastCGI转发(和原有CI4的PHP配置一致) location = /auth/check-access { internal; # 禁止外部直接访问,仅允许内部请求 fastcgi_pass unix:/run/php/php8.2-fpm.sock; # 根据你的PHP版本调整 fastcgi_param SCRIPT_FILENAME $document_root/index.php; fastcgi_param PATH_INFO /Auth/checkAccess; # 对应CI4控制器方法路径 include fastcgi_params; } }
方案二:签名URL(适合临时访问场景)
由CI4生成带签名的临时URL,Nginx验证签名通过后返回文件,适合需要给用户开放短期访问权限的场景。
1. CI4生成签名URL
新增签名工具类:
<?php namespace App\Libraries; class SignedUrl { private $secretKey = 'your-strong-secret-key'; // 替换为你的保密密钥 public function generate(string $filePath, int $expireSeconds = 3600): string { $expire = time() + $expireSeconds; $currentUser = session()->get('user_id'); // 签名内容:用户ID+文件路径+过期时间 $signData = $currentUser . '|' . $filePath . '|' . $expire; $signature = hash_hmac('sha256', $signData, $this->secretKey); // 拼接带参数的URL return $filePath . '?sign=' . $signature . '&expire=' . $expire . '&user=' . $currentUser; } }
在控制器中调用生成签名URL:
$signedUrl = new \App\Libraries\SignedUrl(); $userFileUrl = $signedUrl->generate('/files/user1/img/foo.jpg');
2. Nginx配置(需安装ngx_http_lua_module)
server { # 原有配置... location ^~ /files/ { root /path/to/your/project; access_by_lua_block { local secret_key = "your-strong-secret-key" # 和CI4中的密钥保持一致 local args = ngx.req.get_uri_args() local sign = args.sign or "" local expire = tonumber(args.expire) or 0 local user = args.user or "" local file_path = ngx.var.uri # 检查参数完整性 if sign == "" or expire == 0 or user == "" then ngx.exit(403) end # 检查是否过期 if os.time() > expire then ngx.exit(403) end # 验证签名 local sign_data = user .. "|" .. file_path .. "|" .. expire local expected_sign = ngx.hmac_sha256(secret_key, sign_data) if ngx.encode_base64(expected_sign) ~= sign then # 编码方式需和CI4一致 ngx.exit(403) end # 验证用户目录匹配 local target_user = string.match(file_path, "^/files/([^/]+)/") if target_user ~= user then ngx.exit(403) end } try_files $uri =404; } }
方案三:内部重定向(简单过渡方案)
用户请求友好URL(如/my-files/img/foo.jpg),Nginx先转发给CI4验证权限,CI4通过后触发内部重定向,让Nginx直接返回真实文件。
1. CI4控制器方法
public function serveFile() { $session = session(); $currentUser = $session->get('user_id'); $fileType = $this->request->getGet('type'); // img或pdf $fileName = $this->request->getGet('name'); // 构造真实文件路径 $realPath = "/files/{$currentUser}/{$fileType}/{$fileName}"; $fullPath = FCPATH . $realPath; if (!file_exists($fullPath)) { throw new \CodeIgniter\Exceptions\PageNotFoundException(); } // 发送内部重定向指令给Nginx header("X-Accel-Redirect: " . $realPath); exit; }
2. Nginx配置
server { # 原有配置... # 内部重定向路径,禁止外部直接访问 location ^~ /files/ { internal; root /path/to/your/project; } # 用户访问的友好路径 location /my-files/ { fastcgi_pass unix:/run/php/php8.2-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root/index.php; fastcgi_param PATH_INFO /Auth/serveFile; include fastcgi_params; } }
内容的提问来源于stack exchange,提问作者Alexander Meis
相关产品推荐
相关产品推荐

