isForbidden.php 3.0 KB

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