isForbidden.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <?php
  2. namespace App\Http\Middleware;
  3. use Agent;
  4. use App\Utils\IP;
  5. use Closure;
  6. use Illuminate\Http\Request;
  7. use Log;
  8. use Response;
  9. class isForbidden
  10. {
  11. /**
  12. * 限制机器人、指定IP访问.
  13. */
  14. public function handle(Request $request, Closure $next): mixed
  15. {
  16. // 拒绝机器人访问
  17. if (sysConfig('is_forbid_robot') && Agent::isRobot()) {
  18. Log::warning(trans('errors.forbidden.bots').': '.IP::getClientIp());
  19. return Response::view('auth.error', ['message' => trans('errors.forbidden.bots')], 403);
  20. }
  21. // 拒绝通过非网站链接访问网站,防止网站被探测
  22. if ($this->isForbiddenSubscription($request)) {
  23. Log::warning(trans('errors.forbidden.redirect', ['ip' => IP::getClientIp(), 'url' => $request->fullUrl()]));
  24. return redirect(sysConfig('redirect_url', 'https://www.baidu.com').'?url='.$request->url());
  25. }
  26. // 拒绝特定IP访问
  27. if (sysConfig('forbid_mode') && $this->isForbiddenIP()) {
  28. return Response::view('auth.error', ['message' => trans('errors.forbidden.access')], 403);
  29. }
  30. return $next($request);
  31. }
  32. /**
  33. * 检查是否通过非网站链接访问.
  34. */
  35. private function isForbiddenSubscription(Request $request): bool
  36. {
  37. return config('app.env') === 'production' && sysConfig('website_url') && ! str_contains(sysConfig('website_url'), $request->getHost());
  38. }
  39. /**
  40. * 检查是否为禁止访问的IP.
  41. */
  42. private function isForbiddenIP(): bool
  43. {
  44. $ip = IP::getClientIP();
  45. $ipLocation = IP::getIPInfo($ip);
  46. if (! $ipLocation || empty(array_filter($ipLocation))) {
  47. Log::warning(trans('errors.forbidden.access').": $ip");
  48. return true;
  49. }
  50. if (! in_array($ipLocation['country'], ['本机地址', '局域网'])) {
  51. switch (sysConfig('forbid_mode')) {
  52. case 'ban_mainland':
  53. if (in_array($ipLocation['country'], ['China', '中国', 'CN']) &&
  54. ! in_array($ipLocation['region'], ['Taiwan', 'Hong Kong', 'Macao', '香港', '澳门', '台湾', '台湾省'])) {
  55. Log::warning(trans('errors.forbidden.china').": $ip");
  56. return true;
  57. }
  58. break;
  59. case 'ban_china':
  60. if (in_array($ipLocation['country'], ['China', '中国', 'Taiwan', 'Hong Kong', 'Macao', '香港', '台湾', '澳门'])) {
  61. Log::warning(trans('errors.forbidden.china').": $ip");
  62. return true;
  63. }
  64. break;
  65. case 'ban_oversea':
  66. if (! in_array($ipLocation['country'], ['China', '中国', 'Taiwan', 'Hong Kong', 'Macao', '香港', '台湾', '澳门'])) {
  67. Log::warning(trans('errors.forbidden.oversea').": $ip - ".$ipLocation['country']);
  68. return true;
  69. }
  70. break;
  71. default:
  72. Log::emergency(trans('errors.forbidden.unknown'));
  73. return true;
  74. }
  75. }
  76. return false;
  77. }
  78. }