SpringBoot獲取不到用戶真實IP的解決方法
今天周六,Binvin來總結(jié)一下上周開發(fā)過程中遇到的一個小問題,項目部署后發(fā)現(xiàn)服務(wù)端無法獲取到客戶端真實的IP地址,這是怎么回事呢?給我都整懵逼了,經(jīng)過短暫的思考,我發(fā)現(xiàn)了問題的真兇,那就是我們使用了Nginx作的請求轉(zhuǎn)發(fā),這才導(dǎo)致了獲取不到客戶端真實的IP地址,害,看看我是怎么解決的吧!
問題原因
客戶端請求數(shù)據(jù)時走的是Nginx反向代理,默認(rèn)情況下客戶端的真實IP地址會被其過濾,使得SpringBoot程序無法直接獲得真實的客戶端IP地址,獲取到的都是Nginx的IP地址。
解決方案:
通過更改Nginx配置文件將客戶端真實的IP地址加到請求頭中,這樣就能正常獲取到客戶端的IP地址了,下面我一步步帶你看看如何配置和獲取。
修改Nginx配置文件
在需要做請求轉(zhuǎn)發(fā)的配置里添加下面的配置
#這個參數(shù)設(shè)置了HTTP請求頭的Host字段,host表示請求的Host頭,也就是請求的域名。通過這個設(shè)置,Nginx會將請求的Host頭信息傳遞給后端服務(wù)。 proxy_set_header Host $host; #這個參數(shù)設(shè)置了HTTP請求頭的X?Real?IP字段,remote_addr表示客戶端的IP地址。通過這個設(shè)置,Nginx會將客戶端的真實IP地址傳遞給后端服務(wù) proxy_set_header X-Real-IP $remote_addr; #這個參數(shù)設(shè)置了HTTP請求頭的 X-Forwarded-For字段,"X-Forwarded-For"是一個標(biāo)準(zhǔn)的HTTP請求頭,用于表示HTTP請求經(jīng)過的代理服務(wù)器鏈路信息,proxy_add_x_forwarded_for表示添加額外的服務(wù)器鏈路信息。 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
修改后我的nginx.conf中的server如下所示
server { ? listen 443 ssl; ? server_name xxx.com; ? ssl_certificate "ssl證書pem文件"; ? ssl_certificate_key "ssl證書key文件"; ? ssl_session_timeout 5m; ? ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ? ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ? ssl_prefer_server_ciphers on; ? location / { ? ? root ? 前端html文件目錄; ? ? index ?index.html index.htm; ? } ? error_page ? 500 502 503 504 ?/50x.html; ? location = /50x.html { ? ? root html; ? } ? # 關(guān)鍵在下面這個配置,上面的配置自己根據(jù)情況而定就行 ? location /hello{ ? ? proxy_pass http://127.0.0.1:8090; ? ? proxy_set_header Host $host; ? ? proxy_set_header X-Real-IP $remote_addr;? ? ? proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ? } }
SpringBoot代碼實現(xiàn)
第一種方式:在代碼中直接通過X-Forwarded-For獲取到真實IP地址
@Slf4j public class CommonUtil { /** * <p> 獲取當(dāng)前請求客戶端的IP地址 </p> * * @param request 請求信息 * @return ip地址 **/ public static String getIp(HttpServletRequest request) { if (request == null) { return null; } String unknown = "unknown"; // 使用X-Forwarded-For就能獲取到客戶端真實IP地址 String ip = request.getHeader("X-Forwarded-For"); log.info("X-Forwarded-For:" + ip); if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); log.info("Proxy-Client-IP:" + ip); } if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); log.info("WL-Proxy-Client-IP:" + ip); } if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); log.info("HTTP_X_FORWARDED_FOR:" + ip); } if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED"); log.info("HTTP_X_FORWARDED:" + ip); } if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_CLUSTER_CLIENT_IP"); log.info("HTTP_X_CLUSTER_CLIENT_IP:" + ip); } if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); log.info("HTTP_CLIENT_IP:" + ip); } if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_FORWARDED_FOR"); log.info("HTTP_FORWARDED_FOR:" + ip); } if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_FORWARDED"); log.info("HTTP_FORWARDED:" + ip); } if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_VIA"); log.info("HTTP_VIA:" + ip); } if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) { ip = request.getHeader("REMOTE_ADDR"); log.info("REMOTE_ADDR:" + ip); } if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); log.info("getRemoteAddr:" + ip); } return ip; }
第二種方式:在application.yml文件中加以下配置,直接通過request.getRemoteAddr()并可以獲取到真實IP
server: port: 8090 tomcat: #Nginx轉(zhuǎn)發(fā) 獲取客戶端真實IP配置 remoteip: remote-ip-header: X-Real-IP protocol-header: X-Forwarded-Proto
到此這篇關(guān)于SpringBoot獲取不到用戶真實IP的解決方法的文章就介紹到這了,更多相關(guān)SpringBoot獲取不到用戶真實IP內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java面試題-實現(xiàn)復(fù)雜鏈表的復(fù)制代碼分享
這篇文章主要介紹了Java面試題-實現(xiàn)復(fù)雜鏈表的復(fù)制代碼分享,小編覺得還是挺不錯的,具有參考價值,需要的朋友可以了解下。2017-10-10java volatile關(guān)鍵字的含義詳細(xì)介紹
這篇文章主要介紹了java volatile關(guān)鍵字的含義詳解的相關(guān)資料,需要的朋友可以參考下2016-12-12spring boot定時任務(wù)接收郵件并且存儲附件的方法講解
今天小編就為大家分享一篇關(guān)于spring boot定時任務(wù)接收郵件并且存儲附件的方法講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03詳解springboot采用多數(shù)據(jù)源對JdbcTemplate配置的方法
在本篇文章中我們給大家詳細(xì)分享了springboot采用多數(shù)據(jù)源對JdbcTemplate配置的方法,有需要的朋友們可以學(xué)習(xí)參考下。2018-10-10SpringCloud Netfilx Ribbon負(fù)載均衡工具使用方法介紹
Ribbon是Netflix的組件之一,負(fù)責(zé)注冊中心的負(fù)載均衡,有助于控制HTTP和TCP客戶端行為。Spring Cloud Netflix Ribbon一般配合Ribbon進(jìn)行使用,利用在Eureka中讀取的服務(wù)信息,在調(diào)用服務(wù)節(jié)點時合理進(jìn)行負(fù)載2022-12-12