1、nginx 代理后客户端获取不到真实的ip需要nginx添加配置
location /api {
proxy_pass http://127.0.0.1:8181/;
#以下为新增
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; #获取客户端真实IP
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
添加配置后进行重启:进入nginx可执行目录sbin下,输入命令./nginx -s reload 即可
2、搜集的各种获取IP地址的方法
package com.sany.utils;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sany.vo.IpVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.HttpURLConnection;
import java.net.URL;
public class IPUtils {
private final static Logger logger = LoggerFactory.getLogger(IPUtils.class);
public static String getVisitorIp(HttpServletRequest request){
// 优先取 X-Real-IP
String ip = request.getHeader("X-Real-IP");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
ip = request.getHeader("x-forwarded-for");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
ip = request.getRemoteAddr();
if ("0:0:0:0:0:0:0:1".equals(ip))
{
ip = "unknown";
}
}
if ("unknown".equalsIgnoreCase(ip)){
ip = "unknown";
return ip;
}
int index = ip.indexOf(',');
if (index >= 0){
ip = ip.substring(0, index);
}
return ip;
}
public static final String UN_KNOWN = "unknown";
public static String getIp(HttpServletRequest request) {
String ip = request.getHeader("X-Requested-For");
if (StringUtils.isBlank(ip) || UN_KNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Forwarded-For");
}
if (StringUtils.isBlank(ip) || UN_KNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isBlank(ip) || UN_KNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isBlank(ip) || UN_KNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isBlank(ip) || UN_KNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isBlank(ip) || UN_KNOWN.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return StringUtils.isBlank(ip) ? null : ip.split(",")[0];
}
/**
* 获取用户真实IP地址,不使用request.getRemoteAddr()的原因是有可能用户使用了代理软件方式避免真实IP地址,
* 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值
*
* @return ip
*/
public static String getIpAddrs(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
System.out.println("x-forwarded-for ip: " + ip);
logger.info("x-forwarded-for ip: {}" , ip);
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
// 多次反向代理后会有多个ip值,第一个ip才是真实ip
if( ip.indexOf(",")!=-1 ){
ip = ip.split(",")[0];
}
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
System.out.println("Proxy-Client-IP ip: " + ip);
logger.info("Proxy-Client-IP ip: {}" , ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
logger.info("WL-Proxy-Client-IP ip: {} " , ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
logger.info("HTTP_CLIENT_IP ip: {} " ,ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
logger.info("HTTP_X_FORWARDED_FOR ip: {}" , ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
logger.info("X-Real-IP ip: {}" , ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
logger.info("getRemoteAddr ip: {}" , ip);
}
logger.info("获取客户端ip:{} " ,ip);
return ip;
}
/**
* 获取访问者的ip地址
* 注:要外网访问才能获取到外网地址,如果你在局域网甚至本机上访问,获得的是内网或者本机的ip
*/
public static String getIpAddr(HttpServletRequest request) {
String ipAddress = null;
try {
//X-Forwarded-For:Squid 服务代理
String ipAddresses = request.getHeader("X-Forwarded-For");
if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
//Proxy-Client-IP:apache 服务代理
ipAddresses = request.getHeader("Proxy-Client-IP");
}
if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
//WL-Proxy-Client-IP:weblogic 服务代理
ipAddresses = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
//HTTP_CLIENT_IP:有些代理服务器
ipAddresses = request.getHeader("HTTP_CLIENT_IP");
}
if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
//X-Real-IP:nginx服务代理
ipAddresses = request.getHeader("X-Real-IP");
}
//有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP
if (ipAddresses != null && ipAddresses.length() != 0) {
ipAddress = ipAddresses.split(",")[0];
}
//还是不能获取到,最后再通过request.getRemoteAddr();获取
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
ipAddress = request.getRemoteAddr();
}
} catch (Exception e) {
ipAddress = "";
}
return ipAddress;
}
/**
* 调用太平洋网络IP地址查询Web接口(http://whois.pconline.com.cn/),返回ip、地理位置
*/
public static IpVo getIpVo(String ip){
//查本机
String url = "http://whois.pconline.com.cn/ipJson.jsp?json=true";
//查指定ip
if(!StringUtils.isEmpty(ip)){
url = "http://whois.pconline.com.cn/ipJson.jsp?json=true&ip=" + ip;
}
StringBuilder inputLine = new StringBuilder();
String read;
try {
HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestProperty("Charset", "GBK");
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "GBK"));
while ((read = in.readLine()) != null) {
inputLine.append(read);
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}
//返回格式
/*
{
ip: "58.63.47.115",
pro: "广东省",
proCode: "440000",
city: "广州市",
cityCode: "440100",
region: "天河区",
regionCode: "440106",
addr: "广东省广州市天河区 电信",
regionNames: "",
err: ""
}
*/
IpVo ipVo = null;
try {
ObjectMapper mapper = new ObjectMapper();
//当属性的值为空(null或者"")时,不进行序列化,可以减少数据传输
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
//设置日期格式
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
//转换成IpVo
ipVo = mapper.readValue(new String(inputLine.toString().getBytes("GBK"), "GBK"), IpVo.class);
} catch (IOException e) {
e.printStackTrace();
}
return ipVo;
}
/**
* 直接根据访问者的Request,返回ip、地理位置
*/
public static IpVo getIpVoByRequest(HttpServletRequest request){
return IPUtils.getIpVo(IPUtils.getIpAddr(request));
}
/**
* 获取客户端IP
**/
public static String getClientIp(HttpServletRequest request){
if (request.getHeader("x-forwarded-for") == null){
return request.getRemoteAddr();
}
return request.getHeader("x-forwarded-for");
}
/*
终极大法:java获取不了,就用js来获取
<!-- js获取客户ip -->
<script src="http://whois.pconline.com.cn/ipJson.jsp"></script>
*/
//测试
public static void main(String[] args) {
//获取本机ip
System.out.println(getIpVo(null));
}
}
版权声明:本文为qq_28326501原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。