在 ThinkPHP 6 中实现全局域名过滤(即只允许指定域名访问,拒绝其他域名的请求),可以通过中间件来实现,确保所有请求在进入业务逻辑前先经过域名验证。以下是具体步骤:
步骤 1:创建域名过滤中间件
-
首先生成一个中间件文件,执行命令:
bash
php think make:middleware DomainFilter生成的文件路径为:
app/middleware/DomainFilter.php -
编辑中间件逻辑,实现域名白名单过滤:
php
<?php namespace app\middleware; use think\facade\Request; use think\response\Redirect; // 可选,用于跳转 use think\exception\HttpException; class DomainFilter { // 允许访问的域名白名单(不含协议,支持通配符*) protected $allowDomains = [ 'example.com', // 允许主域名 '*.example.com', // 允许所有子域名 'test.com', // 允许其他域名 ]; public function handle($request, \Closure $next) { // 获取当前请求的主机名(不含协议和端口,如:www.example.com) $currentHost = Request::host(); // 检查当前域名是否在白名单中 if (!$this->isAllowed($currentHost)) { // 拒绝访问:返回403错误或跳转 throw new HttpException(403, '禁止访问:无效的域名'); // 或跳转至指定页面:return redirect('https://example.com/error'); } // 验证通过,继续执行后续请求 return $next($request); } /** * 验证当前域名是否在白名单中(支持通配符) * @param string $host 当前主机名 * @return bool */ protected function isAllowed(string $host): bool { foreach ($this->allowDomains as $allow) { // 处理通配符(如 *.example.com 匹配 a.example.com、b.example.com 等) $pattern = str_replace(['.', '*'], ['.', '.*'], $allow); if (preg_match("/^{$pattern}$/", $host)) { return true; } } return false; } }
步骤 2:注册全局中间件
将中间件添加到全局中间件列表,确保所有请求都经过过滤:
-
编辑
app/middleware.php文件(全局中间件配置):php
<?php return [ // 其他全局中间件... \app\middleware\DomainFilter::class, // 添加域名过滤中间件 ];注意:中间件执行顺序是数组的顺序,建议将域名过滤放在靠前的位置(如最顶部),避免无效请求进入后续逻辑。
步骤 3:测试验证
- 使用白名单中的域名访问:请求正常处理。
- 使用非白名单域名访问:返回 403 错误(或自定义跳转),实现全局域名过滤。
扩展说明
-
动态配置白名单:若需要从数据库或配置文件读取白名单,可在中间件的
__construct方法中加载,例如:php
public function __construct() { // 从配置文件读取(需在 config 目录下定义 domain.php 配置) $this->allowDomains = config('domain.allow_list', []); } -
排除特定路由:若部分路由不需要过滤(如 API 接口),可在中间件中通过
$request->pathinfo()判断路径并跳过,例如:php
if (strpos($request->pathinfo(), 'api/') === 0) { return $next($request); // 跳过API路由的过滤 } -
HTTPS 强制校验:若需要同时限制协议(如只允许 HTTPS),可在中间件中添加协议验证:
php
if (!Request::isSsl()) { throw new HttpException(403, '请使用HTTPS访问'); }
通过以上方法,即可在 TP6 中实现全局、灵活的域名过滤功能。