۱۴۰۰ آذر ۴, پنجشنبه

گرفتن IP کاربر در Spring Boot

به دلیل امنیتی، لازم که بتونیم IP کاربران رو ثبت کنیم. در یک برنامه معمولی Spring Boot مستقیما با کاربران تعامل دارد (بدون پراکسی، لود بالانس و غیره)، می‌توانیم به راحتی با استفاده متد getRemoteHost() از HttpServletRequest اقدام به گرفتن IP کاربران کنیم.

اما در بیشتر موارد، باید اپلیکیشن را پشت Nginx یا آپاچی قرار دهیم و درخواست ها رو به اپلیکیشن بفرستیم‌. در این حالت HttpServletRequest.getRemoteHost() آدرس IP پراکسی سرور را برمی‌گرداند. در نتیجه ما باید IP کاربران را در هدر درخواست ها ست کنیم. معمولا X-FORWARDED-FOR برای این منظور استفاده میشود، ولی تنها این گزینه نیست:

  • X-Forwarded-For
  • Proxy-Client-IP
  • WL-Proxy-Client-IP
  • HTTP_X_FORWARDED_FOR
  • HTTP_X_FORWARDED
  • HTTP_X_CLUSTER_CLIENT_IP
  • HTTP_CLIENT_IP
  • HTTP_FORWARDED_FOR
  • HTTP_FORWARDED
  • HTTP_VIA
  • REMOTE_ADDR

این گزینه ها را در فایل properties اپلیکیشن قرار می‌دهیم و سپس به راحتی، مانند کد پایین، میتوانیم آنها را چک کنیم:


application:
  header-ip-candidates: X-Forwarded-For,Proxy-Client-IP,WL-Proxy-Client-IP,HTTP_X_FORWARDED_FOR,HTTP_X_FORWARDED,HTTP_X_CLUSTER_CLIENT_IP,HTTP_CLIENT_IP,HTTP_FORWARDED_FOR,HTTP_FORWARDED,HTTP_VIA,REMOTE_ADDR

@RestController
@RequestMapping("/ip")
public class IPResource {

    @Value("${application.header-ip-candidates}")
    private String[] headerCandidates;

    @GetMapping
    public ResponseEntity getHome() {
        if (RequestContextHolder.getRequestAttributes() == null) {
            return ResponseEntity.ok("0.0.0.0");
        }

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        for (String header: headerCandidates) {
            String ipList = request.getHeader(header);
            if (ipList != null && ipList.length() != 0 && !"unknown".equalsIgnoreCase(ipList)) {
                String ip = ipList.split(",")[0];
                return ResponseEntity.ok(ip);
            }
        }
        return ResponseEntity.ok(request.getRemoteAddr());
    }
}

هیچ نظری موجود نیست:

ارسال یک نظر