isForbidden.php 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. <?php
  2. namespace App\Http\Middleware;
  3. use Agent;
  4. use App\Components\IPIP;
  5. use App\Components\QQWry;
  6. use Closure;
  7. use Illuminate\Http\Request;
  8. use Log;
  9. class isForbidden {
  10. /**
  11. * 限制机器人、指定IP访问
  12. *
  13. * @param Request $request
  14. * @param Closure $next
  15. *
  16. * @return mixed
  17. */
  18. public function handle($request, Closure $next) {
  19. // 拒绝机器人访问
  20. if(sysConfig('is_forbid_robot') && Agent::isRobot()){
  21. Log::info("识别到机器人访问(".getClientIp().")");
  22. return response()->view('auth.error', ['message' => trans('error.ForbiddenRobot')], 404);
  23. }
  24. // 拒绝通过订阅链接域名访问网站,防止网站被探测
  25. if(true === strpos(sysConfig('subscribe_domain'), $request->getHost())
  26. && !str_contains(sysConfig('subscribe_domain'), sysConfig('website_url'))){
  27. Log::info("识别到通过订阅链接访问,强制跳转至百度(".getClientIp().")");
  28. return redirect('https://www.baidu.com');
  29. }
  30. $ip = getClientIP();
  31. if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)){
  32. Log::info('识别到IPv6,尝试解析:'.$ip);
  33. $isIPv6 = true;
  34. $ipInfo = getIPInfo($ip);
  35. }else{
  36. $isIPv6 = false;
  37. $ipInfo = QQWry::ip($ip); // 通过纯真IP库解析IPv4信息
  38. if(isset($ipInfo['error'])){
  39. Log::info('无法识别IPv4,尝试使用IPIP的IP库解析:'.$ip);
  40. $ipip = IPIP::ip($ip);
  41. $ipInfo = [
  42. 'country' => $ipip['country_name'],
  43. 'province' => $ipip['region_name'],
  44. 'city' => $ipip['city_name']
  45. ];
  46. }else{
  47. // 判断纯真IP库获取的国家信息是否与IPIP的IP库获取的信息一致,不一致则用IPIP的(因为纯真IP库的非大陆IP准确率较低)
  48. $ipip = IPIP::ip($ip);
  49. if($ipInfo['country'] != $ipip['country_name']){
  50. $ipInfo['country'] = $ipip['country_name'];
  51. $ipInfo['province'] = $ipip['region_name'];
  52. $ipInfo['city'] = $ipip['city_name'];
  53. }
  54. }
  55. }
  56. // 拒绝无IP请求
  57. if(empty($ipInfo) || empty($ipInfo['country'])){
  58. return response()->view('auth.error', ['message' => trans('error.ForbiddenAccess')], 403);
  59. }
  60. if(!in_array($ipInfo['country'], ['本机地址', '局域网'])){
  61. // 拒绝大陆IP访问
  62. if(sysConfig('is_forbid_china')){
  63. if(($isIPv6 && $ipInfo['country'] === 'China')
  64. || ($ipInfo['country'] === '中国'
  65. && !in_array($ipInfo['province'], ['香港', '澳门', '台湾']))){
  66. Log::info('识别到大陆IP,拒绝访问:'.$ip);
  67. return response()->view('auth.error', ['message' => trans('error.ForbiddenChina')], 403);
  68. }
  69. }
  70. // 拒绝非大陆IP访问
  71. if(sysConfig('is_forbid_oversea')){
  72. if(($isIPv6 && $ipInfo['country'] !== 'China') || $ipInfo['country'] !== '中国'
  73. || in_array($ipInfo['province'], ['香港', '澳门', '台湾'])){
  74. Log::info('识别到海外IP,拒绝访问:'.$ip.' - '.$ipInfo['country']);
  75. return response()->view('auth.error', ['message' => trans('error.ForbiddenOversea')], 403);
  76. }
  77. }
  78. }
  79. return $next($request);
  80. }
  81. }