CodeIgniter实现URL仅允许iframe调用,禁止浏览器地址栏直接访问
嘿,这个需求我之前在CodeIgniter项目里实操过,核心思路就是利用HTTP请求的**Referer(来源页)**信息判断请求是否来自你的父页面iframe,再结合框架特性做校验。下面给你两种实用的实现方案:
方案一:在目标控制器内直接校验(适合单个/少数页面)
这种方式最直接,把校验逻辑写在目标页面的控制器构造函数里,每次加载页面都会自动触发检查:
class IframePage extends CI_Controller { public function __construct() { parent::__construct(); // 调用校验方法 $this->validate_iframe_access(); } private function validate_iframe_access() { // 获取请求的来源页地址 $referer = $this->input->server('HTTP_REFERER'); // 定义允许的父页面域名/完整URL(比如你的父页面是https://your-site.com/parent-page) $allowed_referer = 'https://your-site.com'; // 校验逻辑:无来源页,或来源页不在允许范围内则拒绝访问 if (empty($referer) || strpos($referer, $allowed_referer) === false) { // 可选:跳转到403禁止访问页面 show_error('禁止直接访问该页面', 403); // 或者重定向到网站首页 // redirect('/'); exit; } } public function index() { // 你的iframe页面逻辑 $this->load->view('iframe_content'); } }
⚠️ 注意:Referer可能被部分浏览器禁用或篡改,如果是敏感页面,建议搭配下面的token验证方案增强安全性。
方案二:用CodeIgniter钩子批量校验(适合多个页面)
如果有大量页面需要限制直接访问,用钩子可以避免重复写代码,实现全局校验:
步骤1:开启钩子
打开application/config/config.php,将钩子开关设为TRUE:
$config['enable_hooks'] = TRUE;
步骤2:配置钩子
打开application/config/hooks.php,添加一个pre_controller钩子(控制器加载前触发):
$hook['pre_controller'][] = array( 'class' => 'IframeAccessChecker', 'function' => 'check_access', 'filename' => 'IframeAccessChecker.php', 'filepath' => 'hooks', 'params' => array( 'allowed_referers' => array('https://your-site.com', 'https://www.your-site.com'), // 排除不需要校验的控制器/方法 'excluded_routes' => array( 'welcome/index', 'auth/login' ) ) );
步骤3:编写钩子处理类
在application/hooks/目录下新建IframeAccessChecker.php:
class IframeAccessChecker { public function check_access($params) { $CI =& get_instance(); $current_route = $CI->router->fetch_class() . '/' . $CI->router->fetch_method(); // 跳过不需要校验的路由 if (in_array($current_route, $params['excluded_routes'])) { return; } $referer = $CI->input->server('HTTP_REFERER'); $access_allowed = false; // 校验来源页是否在允许列表内 foreach ($params['allowed_referers'] as $allowed) { if (!empty($referer) && strpos($referer, $allowed) !== false) { $access_allowed = true; break; } } if (!$access_allowed) { show_error('禁止直接访问该页面', 403); exit; } } }
进阶增强:搭配Token验证(应对Referer不可靠的情况)
如果担心Referer被篡改,可以在父页面加载iframe时传递一个加密token,目标页面校验token有效性:
父页面生成Token
在父页面控制器里生成加密的临时token:
// 确保已加载加密类 $this->load->library('encryption'); // 生成带时间戳的token,设置5分钟有效期 $token = $this->encryption->encode('iframe_access_' . time()); // 传递给iframe的URL $iframe_src = site_url('iframe_page/index?token=' . urlencode($token));
目标页面校验Token
在目标控制器的校验方法里添加token验证:
private function validate_token() { $token = $this->input->get('token'); if (empty($token)) { show_error('无效访问', 403); exit; } try { $decrypted = $this->encryption->decode($token); // 校验标识和有效期 if (strpos($decrypted, 'iframe_access_') === false) { show_error('无效访问', 403); exit; } $timestamp = str_replace('iframe_access_', '', $decrypted); if (time() - $timestamp > 300) { // 5分钟有效期 show_error('访问已过期', 403); exit; } } catch (Exception $e) { show_error('无效访问', 403); exit; } }
⚠️ 注意:要在application/config/config.php里设置加密密钥:
$config['encryption_key'] = 'your-strong-secret-key-here';
内容的提问来源于stack exchange,提问作者Rajal Pathak
相关产品推荐
相关产品推荐

