最近项目要做一个获取登陆者ip的功能,项目架构采用的是springboot+vue前后端分离,而我当我开始用java代码获取客户端请求ip时一直获取到的是服务器的ip也就是vue项目运行机器的ip。
而且很神奇的事情是 vue项目 有前台和后台两个项目 前台采用的是vue-cli2 后台是vue-cli3,而cli3构建项目发送过来的请求是可以正常拿到客户端ip的,而cli2一直拿到的是本机ip,猜想可能是代理的问题,因为vue在dev模式时是自己开的虚拟服务器,并且vue项目中用到了代理。
通过百度发现,一般获取客户端ip java会从请求的remote_addr里面去取,如果中间有代理,就需要从请求头里面的x_forwarded_for里面去取, 而通过debug发现,vue项目走了代理,但是从请求头里x_forwarded_for取不到值, 就定位到 是代理软件的原因了,
一般经过了代理软件,会自动在请求头x_forwarded_for里面加上上一级ip , 而出现这个问题很明显是那个vue2项目在自己代理时 没有做 自动在请求头x_forwarded_for里面加上上一级ip 这个操作,导致获取不到,所以我尝试用nginx代理,代理时要设置请求头参数
server {
listen 9670;
server_name localhost;
# 404页面跳转
location / {
try_files $uri /index.html;
}
root D:/oo/dist;
index index.html index.htm;
location /aa/ {
#代理请求头相关
#proxy_set_header Host $host;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http:ip:port;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
此时 就能拿到 客户端发起请求的真实ip了
解决方案:
1.如果是vue开发环境,在vue里面代理时要设置 代理加上
proxy_set_header X-Forwarded-For $remote_addr;
2.若是打包成dist 则nginx像上面那样配置就好
核心就是 nginx代理是 要让他在请求头里面带上参数
#代理请求头相关
#proxy_set_header Host $host;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http:ip:port;
附
java从请求里面拿ip的方法
/**
* new
* @param request
* @return
*/
public static String getIpAddressNew(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
System.out.println("HTTP_X_FORWARDED_FOR:--------------"+ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_CLUSTER_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_FORWARDED");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_VIA");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("REMOTE_ADDR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
if (ip.contains(",")) {
return ip.split(",")[0];
} else {
return ip;
}
}
或
public static String getIpAddr(HttpServletRequest request)
{
if (request == null)
{
return "unknown";
}
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("Proxy-Client-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.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
ip = request.getRemoteAddr();
}
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : EscapeUtil.clean(ip);
}
附:
https://blog.csdn.net/qq_28796345/article/details/88685245