最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot通過Nginx代理獲取真實(shí)IP

 更新時間:2024年01月16日 09:11:47   作者:北風(fēng)濁酒  
springboot作為后臺代碼,獲取到的登錄IP是前臺的代理服務(wù)器地址,并不是用戶的真實(shí)IP地址,本文主要介紹了SpringBoot通過Nginx代理獲取真實(shí)IP,具有一定的參考價(jià)值,感興趣的可以了解一下

springboot作為后臺代碼,獲取到的登錄IP是前臺的代理服務(wù)器地址,并不是用戶的真實(shí)IP地址,讓我們在做統(tǒng)計(jì)的時候無從下手。下面是一個后臺獲取IP地址的類,本質(zhì)上沒有什么問題,問題在于,Nginx給你的就是一個代理之后的地址,所以你當(dāng)然獲取不到真實(shí)的地址了。

package com.**.common.core.utils.ip;

import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.servlet.http.HttpServletRequest;
import com.**.common.core.utils.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;

/**
 * 獲取IP方法
 * 
 * @author Hxhh
 */
public class IpUtils
{
    /**
     * 獲取客戶端IP
     * 
     * @param request 請求對象
     * @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" : getMultistageReverseProxyIp(ip);
    }

    public static String getIpAddr(ServerHttpRequest request) {
        HttpHeaders headers = request.getHeaders();
        String ip = headers.getFirst("x-forwarded-for");
        if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
            // 多次反向代理后會有多個ip值,第一個ip才是真實(shí)ip
            if (ip.indexOf(",") != -1) {
                ip = ip.split(",")[0];
            }
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = headers.getFirst("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = headers.getFirst("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = headers.getFirst("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = headers.getFirst("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = headers.getFirst("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddress().getAddress().getHostAddress();
        }
        return ip;
    }


    /**
     * 檢查是否為內(nèi)部IP地址
     * 
     * @param ip IP地址
     * @return 結(jié)果
     */
    public static boolean internalIp(String ip)
    {
        byte[] addr = textToNumericFormatV4(ip);
        return internalIp(addr) || "127.0.0.1".equals(ip);
    }

    /**
     * 檢查是否為內(nèi)部IP地址
     * 
     * @param addr byte地址
     * @return 結(jié)果
     */
    private static boolean internalIp(byte[] addr)
    {
        if (StringUtils.isNull(addr) || addr.length < 2)
        {
            return true;
        }
        final byte b0 = addr[0];
        final byte b1 = addr[1];
        // 10.x.x.x/8
        final byte SECTION_1 = 0x0A;
        // 172.16.x.x/12
        final byte SECTION_2 = (byte) 0xAC;
        final byte SECTION_3 = (byte) 0x10;
        final byte SECTION_4 = (byte) 0x1F;
        // 192.168.x.x/16
        final byte SECTION_5 = (byte) 0xC0;
        final byte SECTION_6 = (byte) 0xA8;
        switch (b0)
        {
            case SECTION_1:
                return true;
            case SECTION_2:
                if (b1 >= SECTION_3 && b1 <= SECTION_4)
                {
                    return true;
                }
            case SECTION_5:
                switch (b1)
                {
                    case SECTION_6:
                        return true;
                }
            default:
                return false;
        }
    }

    /**
     * 將IPv4地址轉(zhuǎn)換成字節(jié)
     * 
     * @param text IPv4地址
     * @return byte 字節(jié)
     */
    public static byte[] textToNumericFormatV4(String text)
    {
        if (text.length() == 0)
        {
            return null;
        }

        byte[] bytes = new byte[4];
        String[] elements = text.split("\\.", -1);
        try
        {
            long l;
            int i;
            switch (elements.length)
            {
                case 1:
                    l = Long.parseLong(elements[0]);
                    if ((l < 0L) || (l > 4294967295L))
                    {
                        return null;
                    }
                    bytes[0] = (byte) (int) (l >> 24 & 0xFF);
                    bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
                    bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
                    bytes[3] = (byte) (int) (l & 0xFF);
                    break;
                case 2:
                    l = Integer.parseInt(elements[0]);
                    if ((l < 0L) || (l > 255L))
                    {
                        return null;
                    }
                    bytes[0] = (byte) (int) (l & 0xFF);
                    l = Integer.parseInt(elements[1]);
                    if ((l < 0L) || (l > 16777215L))
                    {
                        return null;
                    }
                    bytes[1] = (byte) (int) (l >> 16 & 0xFF);
                    bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
                    bytes[3] = (byte) (int) (l & 0xFF);
                    break;
                case 3:
                    for (i = 0; i < 2; ++i)
                    {
                        l = Integer.parseInt(elements[i]);
                        if ((l < 0L) || (l > 255L))
                        {
                            return null;
                        }
                        bytes[i] = (byte) (int) (l & 0xFF);
                    }
                    l = Integer.parseInt(elements[2]);
                    if ((l < 0L) || (l > 65535L))
                    {
                        return null;
                    }
                    bytes[2] = (byte) (int) (l >> 8 & 0xFF);
                    bytes[3] = (byte) (int) (l & 0xFF);
                    break;
                case 4:
                    for (i = 0; i < 4; ++i)
                    {
                        l = Integer.parseInt(elements[i]);
                        if ((l < 0L) || (l > 255L))
                        {
                            return null;
                        }
                        bytes[i] = (byte) (int) (l & 0xFF);
                    }
                    break;
                default:
                    return null;
            }
        }
        catch (NumberFormatException e)
        {
            return null;
        }
        return bytes;
    }

    /**
     * 獲取IP地址
     * 
     * @return 本地IP地址
     */
    public static String getHostIp()
    {
        try
        {
            return InetAddress.getLocalHost().getHostAddress();
        }
        catch (UnknownHostException e)
        {
        }
        return "127.0.0.1";
    }

    /**
     * 獲取主機(jī)名
     * 
     * @return 本地主機(jī)名
     */
    public static String getHostName()
    {
        try
        {
            return InetAddress.getLocalHost().getHostName();
        }
        catch (UnknownHostException e)
        {
        }
        return "未知";
    }

    /**
     * 從多級反向代理中獲得第一個非unknown IP地址
     *
     * @param ip 獲得的IP地址
     * @return 第一個非unknown IP地址
     */
    public static String getMultistageReverseProxyIp(String ip)
    {
        // 多級反向代理檢測
        if (ip != null && ip.indexOf(",") > 0)
        {
            final String[] ips = ip.trim().split(",");
            for (String subIp : ips)
            {
                if (false == isUnknown(subIp))
                {
                    ip = subIp;
                    break;
                }
            }
        }
        return ip;
    }

    /**
     * 檢測給定字符串是否為未知,多用于檢測HTTP請求相關(guān)
     *
     * @param checkString 被檢測的字符串
     * @return 是否未知
     */
    public static boolean isUnknown(String checkString)
    {
        return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
    }
}

那么如何識別客戶端的真實(shí)IP呢,需要通過兩種方式去判斷:

1、沒有代理
如果只是普通的web項(xiàng)目的話,通過 request.getRemoteAddr(); (HttpServletRequest 類型) 即可獲取到客戶端的真實(shí)IP

2、Nginx代理
在有代理的情況下,由于任何請求首先經(jīng)過Nginx,故通過request.getRemoteAddr()獲取的其實(shí)是Nginx的IP,并非真實(shí)的客戶端IP;此時通過x-forwarded-for獲取的IP為:"客戶端,代理1,代理2,..."或者"偽造IP,客戶端,代理1,代理2,...",故不能獲取到準(zhǔn)確的客戶端IP,此時需要配置Nginx TCP客戶端連接的真實(shí)IP,通過代理配置獲取真實(shí)IP,可以通過$remote_addr獲取客戶端IP,Nginx配置如下:

location / {
   //追加如下代碼
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header Host $host;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 
}

然后服務(wù)端通過: request.getHeader("X-Real-IP");    即可獲取到客戶端的真實(shí)IP

到此這篇關(guān)于SpringBoot通過Nginx代理獲取真實(shí)IP的文章就介紹到這了,更多相關(guān)SpringBoot Nginx獲取真實(shí)IP內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java實(shí)現(xiàn)支付寶支付接口的調(diào)用

    java實(shí)現(xiàn)支付寶支付接口的調(diào)用

    本文主要介紹了java實(shí)現(xiàn)支付寶支付接口的調(diào)用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Java 在PPT中創(chuàng)建散點(diǎn)圖的實(shí)現(xiàn)示例

    Java 在PPT中創(chuàng)建散點(diǎn)圖的實(shí)現(xiàn)示例

    本文將以Java代碼示例展示如何在PPT幻燈片中創(chuàng)建散點(diǎn)圖表。文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 超詳細(xì)的Java 問題排查工具單

    超詳細(xì)的Java 問題排查工具單

    這篇文章主要介紹了超詳細(xì)的Java 問題排查工具單,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • java Aop實(shí)現(xiàn)自動填充字段值示例

    java Aop實(shí)現(xiàn)自動填充字段值示例

    這篇文章主要為大家介紹了Aop實(shí)現(xiàn)自動填充字段值示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Java案例之隨機(jī)驗(yàn)證碼功能實(shí)現(xiàn)實(shí)例

    Java案例之隨機(jī)驗(yàn)證碼功能實(shí)現(xiàn)實(shí)例

    本篇文章主要介紹了Java案例之隨機(jī)驗(yàn)證碼功能實(shí)現(xiàn)實(shí)例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • java生成彩色附logo二維碼

    java生成彩色附logo二維碼

    這篇文章主要為大家介紹了java生成帶logo的多彩二維碼,比一般二維碼顏色鮮艷,美觀,如何生成二維碼,下面小編為大家分享實(shí)現(xiàn)代碼,感興趣的小伙伴們可以參考一下
    2016-04-04
  • Spring Boot 2.0 整合 Spring Security OAuth2的完整實(shí)現(xiàn)方案

    Spring Boot 2.0 整合 Spring Security&

    OAuth 2.0是一個行業(yè)標(biāo)準(zhǔn)的授權(quán)協(xié)議,它允許用戶在不將用戶名和密碼提供給第三方應(yīng)用的情況下,授權(quán)第三方應(yīng)用訪問用戶存儲在服務(wù)提供方的資源,本文給大家介紹Spring Boot 2.0 整合 Spring Security OAuth2的完整實(shí)現(xiàn)方案,感興趣的朋友一起看看吧
    2026-03-03
  • Java獲取文件ContentType案例

    Java獲取文件ContentType案例

    這篇文章主要介紹了Java獲取文件ContentType案例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • 深入了解Java語言中的并發(fā)性選項(xiàng)有何不同

    深入了解Java語言中的并發(fā)性選項(xiàng)有何不同

    這篇文章主要介紹了深入了解Java語言中的并發(fā)性選項(xiàng)有何不同,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下
    2019-06-06
  • Jackson常用方法以及jacksonUtil工具類詳解

    Jackson常用方法以及jacksonUtil工具類詳解

    這篇文章主要介紹了Jackson常用方法以及jacksonUtil工具類詳解,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06

最新評論

大邑县| 外汇| 华阴市| 麟游县| 扎兰屯市| 铅山县| 财经| 青冈县| 榆中县| 肇东市| 韶关市| 宁津县| 山阴县| 阿坝县| 佛教| 宁南县| 木兰县| 山东| 合江县| 东山县| 康乐县| 博乐市| 新沂市| 南雄市| 巩义市| 东乡县| 泽普县| 宜良县| 勐海县| 镇安县| 南阳市| 西盟| 始兴县| 唐海县| 卓资县| 伊金霍洛旗| 揭东县| 荔波县| 清远市| 阿巴嘎旗| 集贤县|