isForbidden.php 3.1 KB

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