123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- <?php
- /**
- * Created by PhpStorm.
- * User: wanggb
- * Date: 2018/11/22
- * Time: 19:57
- */
- namespace app\common\service;
- use app\common\constants\DomainBlackList;
- use app\common\library\Redis;
- use app\common\model\Blacklist;
- use app\main\service\UrlService;
- use think\Log;
- class BlacklistService
- {
- const ALLDOMAIN= 'alldomain';
- const DOMAINBYPARAM= 'domainbyparam';
- const DOMAINBYPATH= 'domainbypath';
- /**
- * @var BlacklistService
- */
- private static $self;
- /**
- * @var \Redis
- */
- protected $redis = null;
- protected $domain = null;
- protected $path = null;
- protected $param = null;
- /**
- * @return BlacklistService
- */
- public static function instance()
- {
- if(self::$self == NULL){
- self::$self = new self();
- }
- return self::$self;
- }
- /**
- * 校验域名,如果访问的域名在黑名单列表中,返回404
- * @param $request
- */
- public function checkDomain(&$request)
- {
- $this->redis = Redis::instance();
- //$this->domain = $request->domain();
- $this->domain = UrlService::instance()->getUnlimitDomainOriginWxUrl()->data;
- $this->path = $request->path();
- $this->param = $request->param();
- # redis_key => FFSN:wx7610e3344bdea6f6.dev.kpread.com
- $host_redis_key = DomainBlackList::REDISPREFIX . $this->formatDomain($this->domain);
- $redis_rules = $this->redis->hGetAll($host_redis_key);
- Log::info('domain black rules:' . json_encode($redis_rules, JSON_UNESCAPED_UNICODE));
- $result = false;
- if($redis_rules){
- foreach ($redis_rules as $rule => $item_type){
- if($item_type == DomainBlackList::LOCKALLDOMAIN){
- if($rule == $this->formatDomain($this->domain)){
- $result = true;
- break;
- }
- } elseif($item_type == DomainBlackList::LOCKDOMAINBYPARAM) {
- parse_str($rule, $param_arr);
- $param_flag = false;
- foreach ($param_arr as $arg_key => $arg_value) {
- if (array_key_exists($arg_key, $this->param) && $arg_value == $this->param[$arg_key]) {
- $param_flag = true;
- }
- }
- if ($param_flag) {
- $result = true;
- break;
- }
- }elseif($item_type == DomainBlackList::LOCKDOMAINBYPATH){
- if ($rule == $this->path) {
- $result = true;
- break;
- }
- }
- }
- }
- //$result = $this->validateRule();
- if ($result) {
- # 跳转到 404 页面
- http_response_code(404);
- header('HTTP/1.1 404 Not Found');
- $html = "<html><head><title>页面无法访问</title></head><body><h1 style='text-align: center; margin-top: 15%;'>页面走丢了!</h1></body></html>";
- echo $html;
- exit();
- }
- }
- /**
- * 进行规则校验,成功返回true;
- * @return bool|string
- */
- public function validateRule()
- {
- $rules = $this->getValidateRule();
- foreach ($rules as $key => $item) {
- foreach ($item as $k => $v) {
- if ($key == self::ALLDOMAIN) {
- # 仅校验 domain
- if ($this->domain == $v['domain']) {
- return true;
- break;
- }
- } elseif ($key == self::DOMAINBYPARAM) {
- if ($this->domain == $v['domain']) {
- parse_str($v['param'], $param_arr);
- $param_flag = false;
- foreach ($param_arr as $arg_key => $arg_value) {
- if (array_key_exists($arg_key, $this->param) && $arg_value == $this->param[$arg_key]) {
- $param_flag = true;
- }
- }
- if ($param_flag) {
- return true;
- break;
- }
- }
- } elseif ($key == self::DOMAINBYPATH) {
- # 仅校验 domain
- if ($this->path == $v['path']) {
- return true;
- break;
- }
- }
- }
- }
- }
- /**
- * 获取域名黑名单的校验规则
- * @return array
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function getValidateRule()
- {
- $blackListModel = new Blacklist();
- $black_roles = $blackListModel->where('status', '=', 'active')->order('type')->select();
- $black_group = [];
- if ($black_roles) {
- foreach ($black_roles as $k => $v) {
- if ($v['type'] == DomainBlackList::LOCKALLDOMAIN) {
- $black_group[self::ALLDOMAIN][] = $v;
- } elseif ($v['type'] == DomainBlackList::LOCKDOMAINBYPARAM) {
- $black_group[self::DOMAINBYPARAM][] = $v;
- } elseif ($v['type'] == DomainBlackList::LOCKDOMAINBYPATH) {
- $black_group[self::DOMAINBYPATH][] = $v;
- }
- }
- }
- return $black_group;
- }
- public function getRedisRules()
- {
- $this->redis = Redis::instance();
- $rules = $this->redis->hGetAll();
- }
- /**
- * @param $domain
- * @return mixed
- */
- public function formatDomain($domain)
- {
- $domain = str_replace("https:","http:",$domain);
- preg_match("/^(http:\/\/)?([^\/]+)/i", $domain, $matches);
- return $matches[2];
- }
- }
|