﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-kingmove-文章分类-apache</title><link>http://www.blogjava.net/kingmove/category/39130.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 20 Apr 2009 19:42:16 GMT</lastBuildDate><pubDate>Mon, 20 Apr 2009 19:42:16 GMT</pubDate><ttl>60</ttl><item><title>apache反向代理,如何获取用户真实IP</title><link>http://www.blogjava.net/kingmove/articles/266606.html</link><dc:creator>KingMove</dc:creator><author>KingMove</author><pubDate>Mon, 20 Apr 2009 12:38:00 GMT</pubDate><guid>http://www.blogjava.net/kingmove/articles/266606.html</guid><wfw:comment>http://www.blogjava.net/kingmove/comments/266606.html</wfw:comment><comments>http://www.blogjava.net/kingmove/articles/266606.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kingmove/comments/commentRss/266606.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kingmove/services/trackbacks/266606.html</trackback:ping><description><![CDATA[<div class="content">
<p>很多时候项目都需要获取用户的真实IP进行一些分析或者权限过滤,一般情况下通过<strong>request.getRemoteAddr()就可取得客户端的IP地址,</strong>但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。</p>
<p>如果使用了反向代理软件，将<u><a href="http://192.168.1.110:2046/">http://192.168.1.110:2046/</a></u> 的URL反向代理为<u>http://www.xxx.com/</u> 的URL时，用<strong>request.getRemoteAddr()</strong>方法获取的IP地址是：127.0.0.1　或　<u><font color="#0000ff">192.168.1.110</font></u>，而并不是客户端的真实ＩＰ。</p>
<p>经过代理以后，由于在客户端和服务之间增加了中间层，因此服务器无法直接拿到客户端的IP，服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中，增加了<u><strong>X－FORWARDED－FOR</strong></u>信息用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。<br />
原来如此，我们的项目中正好是有前置apache，将一些请求转发给后端的weblogic，看来就是这样导致的咯。</p>
<p>给出一份还算靠谱的代码，如下：</p>
<p>&nbsp;</p>
<div class="codeText">
<div class="codeHead">Java代码</div>
<ol class="dp-j">
    <li class="alt"><span><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;getIpAddr(HttpServletRequest&nbsp;request)&nbsp;{&nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;ip&nbsp;=&nbsp;request.getHeader(<span class="string">"x-forwarded-for"</span><span>);&nbsp;&nbsp;</span></span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>(ip&nbsp;==&nbsp;</span><span class="keyword">null</span><span>&nbsp;||&nbsp;ip.length()&nbsp;==&nbsp;</span><span class="number">0</span><span>&nbsp;||&nbsp;</span><span class="string">"unknown"</span><span>.equalsIgnoreCase(ip))&nbsp;{&nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip&nbsp;=&nbsp;request.getHeader(<span class="string">"Proxy-Client-IP"</span><span>);&nbsp;&nbsp;</span></span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>(ip&nbsp;==&nbsp;</span><span class="keyword">null</span><span>&nbsp;||&nbsp;ip.length()&nbsp;==&nbsp;</span><span class="number">0</span><span>&nbsp;||&nbsp;</span><span class="string">"unknown"</span><span>.equalsIgnoreCase(ip))&nbsp;{&nbsp;&nbsp;</span></span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip&nbsp;=&nbsp;request.getHeader(<span class="string">"WL-Proxy-Client-IP"</span><span>);&nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>(ip&nbsp;==&nbsp;</span><span class="keyword">null</span><span>&nbsp;||&nbsp;ip.length()&nbsp;==&nbsp;</span><span class="number">0</span><span>&nbsp;||&nbsp;</span><span class="string">"unknown"</span><span>.equalsIgnoreCase(ip))&nbsp;{&nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip&nbsp;=&nbsp;request.getRemoteAddr();&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;ip;&nbsp;&nbsp;</span></span>
    <li class="alt"><span>}&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>如果有人遇到类似问题，请多加留意，呵呵。</p>
<p>&nbsp;</p>
<p>PS：可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串Ｉｐ值，究竟哪个才是真正的用户端的真实IP呢？<br />
答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。如：X-Forwarded-For：192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100,用户真实IP为： 192.168.1.110</p>
<p><strong>参考文章：</strong>http://blog.sina.com.cn/s/blog_407a68fc01000ai7.html</p>
</div>
 <img src ="http://www.blogjava.net/kingmove/aggbug/266606.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kingmove/" target="_blank">KingMove</a> 2009-04-20 20:38 <a href="http://www.blogjava.net/kingmove/articles/266606.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>