跳到正文

ThinkPHP6使用中间件过滤来源网址或IP

使用ThinkPHP6开发接口时会遇到前置过滤或判断,我们可以使用中间件功能。以下是单应用模式示例:

创建中间件

第1种方式,命令行方式:

php think make:middleware Filter

第2种方式,手动在app目录下创建middleware文件夹,再创建中间件类:

<?php

namespace app\middleware;

class Filter
{
    public function handle($request, \Closure $next, $name)
    {
        //to do

        return $next($request);
    }
}

配置过滤参数

需要我们配置好白名单网址和白名单IP,在.env配置文件中增加以下配置:

[FILTER]
HOST = localhost,127.0.0.1,abc.com
IP = 127.0.0.1,192.168.0.253

中间件逻辑

to do中实现过滤来源网址逻辑,失败时返回错误Json。

//来源网址
$origin = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : (isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '');
if($origin != '') {
    $list = env('filter.host', '');
    $lists = explode(',',$list);
    for ($i = 0;$len = count($lists),$i < $len;$i++) {
        if(strpos($origin,$lists[$i]) !== false) {
            $flag = true;
            break;
        }
    }
}
if(!$flag) {
    return json(["errorCode" => 9998,"errorMessage" => '请求来源不正确']);
}

再进一步,增加来源IP判断

//来源IP
$ip = '';
if(isset($_SERVER["HTTP_CLIENT_IP"])) {
    $ip = $_SERVER["HTTP_CLIENT_IP"];
}
else if(isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
    $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
}
else if(isset($_SERVER["REMOTE_ADDR"])) {
    $ip = $_SERVER["REMOTE_ADDR"];
}
if(filter_var($ip,FILTER_VALIDATE_IP)) {
    $list = env('filter.ip', '');
    $lists = explode(',',$list);
    for ($i = 0;$len = count($lists),$i < $len;$i++) {
        if(strpos($ip,$lists[$i]) !== false) {
            $flag = true;
            break;
        }
    }
}

整个中间件逻辑代码如下:

public function handle($request, \Closure $next)
{
    $flag = false;
    //来源网址
    $origin = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_ORIGIN'] : '';
    if($origin != '') {
        $list = env('filter.host', '');
        $lists = explode(',',$list);
        for ($i = 0;$len = count($lists),$i < $len;$i++) {
            if(strpos($origin,$lists[$i]) !== false) {
                $flag = true;
                break;
            }
        }
    }
    if($flag) {
        //来源IP
        $ip = '';
        if(isset($_SERVER["HTTP_CLIENT_IP"])) {
            $ip = $_SERVER["HTTP_CLIENT_IP"];
        }
        else if(isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
            $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
        }
        else if(isset($_SERVER["REMOTE_ADDR"])) {
            $ip = $_SERVER["REMOTE_ADDR"];
        }
        if(filter_var($ip,FILTER_VALIDATE_IP)) {
            $list = env('filter.ip', '');
            $lists = explode(',',$list);
            for ($i = 0;$len = count($lists),$i < $len;$i++) {
                if(strpos($ip,$lists[$i]) !== false) {
                    $flag = true;
                    break;
                }
            }
        }
    }
    if(!$flag) {
        return json(["errorCode" => 9998,"errorMessage" => '请求来源不正确']);
    }
    return $next($request);
}

控制器使用

如果所有控制器都需要使用这个中间件过滤,则在app\middleware.php中增加:

\app\middleware\Filter::class

如果只有需要的控制器才使用这个中间件过滤,则可以在需要的控件器类中增加:

//此类使用中间件
protected $middleware = [Filter::class];

评论 0

还没有评论,快来抢沙发吧。