isForbidden.php 3.2 KB

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