import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
/**
* 网络工具类
*
*/
public class NetUtils {
/**
* 获取客户端 IP 地址
*
* @param request 请求
* @return {@link String}
*/
public static String getIpAddress(HttpServletRequest request) {
String scheme= request.getHeader("X-Forwarded-Scheme");
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
if ("127.0.0.1".equals(ip)) {
// 根据网卡取本机配置的 IP
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (Exception e) {
e.printStackTrace();
}
if (inet != null) {
ip = inet.getHostAddress();
}
}
}
// 多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (ip != null && ip.length() > 15) {
if (ip.indexOf(",") > 0) {
ip = ip.substring(0, ip.indexOf(","));
}
}
if (ip == null) {
return "127.0.0.1";
}
return scheme + "://" + ip;
}
}
有时候,后端需要拿到客户端的访问IP(不是客户机ip)来重定向,由于请求经过n道转发,我们已经拿不到最原始的ip,例如:
比如我们访问:http://127.0.0.1:8080/demo/index.html
第一次将我们请求转发到:http://127.0.0.2:8081
第二次将我们请求转发到:http://127.0.0.3:8082
后端判断是否登录,然后重定向到登录页,由于只有http://127.0.0.1:8080对外网开发了,所以后端重定向也只能重定向到http://127.0.0.1:8080/login.html,但是后端只能拿到最后一次转发的ip
这样在重定向时,往往会报错,这需要我们在nginx里配置:
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
注意:每次转发都需要配置,这样才会把原始访问ip传递下去