SpringBoot獲取不到用戶真實(shí)IP的解決方法
今天周六,Binvin來(lái)總結(jié)一下上周開(kāi)發(fā)過(guò)程中遇到的一個(gè)小問(wèn)題,項(xiàng)目部署后發(fā)現(xiàn)服務(wù)端無(wú)法獲取到客戶端真實(shí)的IP地址,這是怎么回事呢?給我都整懵逼了,經(jīng)過(guò)短暫的思考,我發(fā)現(xiàn)了問(wèn)題的真兇,那就是我們使用了Nginx作的請(qǐng)求轉(zhuǎn)發(fā),這才導(dǎo)致了獲取不到客戶端真實(shí)的IP地址,害,看看我是怎么解決的吧!
問(wèn)題原因
客戶端請(qǐng)求數(shù)據(jù)時(shí)走的是Nginx反向代理,默認(rèn)情況下客戶端的真實(shí)IP地址會(huì)被其過(guò)濾,使得SpringBoot程序無(wú)法直接獲得真實(shí)的客戶端IP地址,獲取到的都是Nginx的IP地址。
解決方案:
通過(guò)更改Nginx配置文件將客戶端真實(shí)的IP地址加到請(qǐng)求頭中,這樣就能正常獲取到客戶端的IP地址了,下面我一步步帶你看看如何配置和獲取。
修改Nginx配置文件
在需要做請(qǐng)求轉(zhuǎn)發(fā)的配置里添加下面的配置
#這個(gè)參數(shù)設(shè)置了HTTP請(qǐng)求頭的Host字段,host表示請(qǐng)求的Host頭,也就是請(qǐng)求的域名。通過(guò)這個(gè)設(shè)置,Nginx會(huì)將請(qǐng)求的Host頭信息傳遞給后端服務(wù)。 proxy_set_header Host $host; #這個(gè)參數(shù)設(shè)置了HTTP請(qǐng)求頭的X?Real?IP字段,remote_addr表示客戶端的IP地址。通過(guò)這個(gè)設(shè)置,Nginx會(huì)將客戶端的真實(shí)IP地址傳遞給后端服務(wù) proxy_set_header X-Real-IP $remote_addr; #這個(gè)參數(shù)設(shè)置了HTTP請(qǐng)求頭的 X-Forwarded-For字段,"X-Forwarded-For"是一個(gè)標(biāo)準(zhǔn)的HTTP請(qǐng)求頭,用于表示HTTP請(qǐng)求經(jīng)過(guò)的代理服務(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證書(shū)pem文件";
? ssl_certificate_key "ssl證書(shū)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)鍵在下面這個(gè)配置,上面的配置自己根據(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代碼實(shí)現(xiàn)
第一種方式:在代碼中直接通過(guò)X-Forwarded-For獲取到真實(shí)IP地址
@Slf4j
public class CommonUtil {
/**
* <p> 獲取當(dāng)前請(qǐng)求客戶端的IP地址 </p>
*
* @param request 請(qǐng)求信息
* @return ip地址
**/
public static String getIp(HttpServletRequest request) {
if (request == null) {
return null;
}
String unknown = "unknown";
// 使用X-Forwarded-For就能獲取到客戶端真實(shí)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文件中加以下配置,直接通過(guò)request.getRemoteAddr()并可以獲取到真實(shí)IP
server:
port: 8090
tomcat:
#Nginx轉(zhuǎn)發(fā) 獲取客戶端真實(shí)IP配置
remoteip:
remote-ip-header: X-Real-IP
protocol-header: X-Forwarded-Proto到此這篇關(guān)于SpringBoot獲取不到用戶真實(shí)IP的解決方法的文章就介紹到這了,更多相關(guān)SpringBoot獲取不到用戶真實(shí)IP內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springcloud+nacos實(shí)現(xiàn)灰度發(fā)布示例詳解
這篇文章主要介紹了springcloud+nacos實(shí)現(xiàn)灰度發(fā)布,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08
Java報(bào)錯(cuò)Non-terminating?decimal?expansion解決分析
這篇文章主要為大家介紹了Java報(bào)錯(cuò)Non-terminating?decimal?expansion解決方案及原理分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
JAVA中string數(shù)據(jù)類(lèi)型轉(zhuǎn)換詳解
在JAVA中string是final類(lèi),提供字符串不可以修改,string類(lèi)型在項(xiàng)目中經(jīng)常使用,下面給大家介紹了string七種數(shù)據(jù)類(lèi)型轉(zhuǎn)換,需要的朋友可以參考下2015-07-07
在已有spring的基礎(chǔ)上集成hibernate的實(shí)例講解
下面小編就為大家?guī)?lái)一篇在已有spring的基礎(chǔ)上集成hibernate的實(shí)例講解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11
SpringCloud Zuul服務(wù)功能與使用方法解析
這篇文章主要介紹了SpringCloud Zuul服務(wù)功能與使用方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
Java實(shí)現(xiàn)對(duì)比兩個(gè)實(shí)體類(lèi)字段變化的示例詳解
我們?cè)诠ぷ髦?可能會(huì)在日志中記錄數(shù)據(jù)的變化情況或者在公共處理的數(shù)據(jù)增加一個(gè)日志頁(yè)面,我們可以根據(jù)CompareUtils工具類(lèi)比較數(shù)據(jù)前后發(fā)生了怎樣的變化,下面我們就來(lái)看看具體實(shí)現(xiàn)吧2024-03-03
springboot中的@value取不到正確的值問(wèn)題
這篇文章主要介紹了springboot中的@value取不到正確的值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12

