request.remote_ip
rails2,rails3都是这样调用,但是两者是有区别的
rails2.3.8中的这个方法封装在ActionController::Request类中
从源代码看
def remote_ip remote_addr_list = @env['REMOTE_ADDR'] && @env['REMOTE_ADDR'].scan(/[^,\s]+/) unless remote_addr_list.blank? not_trusted_addrs = remote_addr_list.reject {|addr| addr =~ TRUSTED_PROXIES} return not_trusted_addrs.first unless not_trusted_addrs.empty? end remote_ips = @env['HTTP_X_FORWARDED_FOR'] && @env['HTTP_X_FORWARDED_FOR'].split(',') if @env.include? 'HTTP_CLIENT_IP' if ActionController::Base.ip_spoofing_check && remote_ips && !remote_ips.include?(@env['HTTP_CLIENT_IP']) # We don't know which came from the proxy, and which from the user raise ActionControllerError.new("IP spoofing attack?!\nHTTP_CLIENT_IP=\#{@env['HTTP_CLIENT_IP'].inspect}\nHTTP_X_FORWARDED_FOR=\#{@env['HTTP_X_FORWARDED_FOR'].inspect}\n") end return @env['HTTP_CLIENT_IP'] end if remote_ips while remote_ips.size > 1 && TRUSTED_PROXIES =~ remote_ips.last.strip remote_ips.pop end return remote_ips.last.strip end @env['REMOTE_ADDR'] end
获取用户登录信息的http头都封装在了@env这个实例变量里面了
rails3.2.6对以前的代码作了优化,并单独封装了ActionDispatch::Request 这个类
源代码也只是剩下下面几行了
# File actionpack/lib/action_dispatch/http/request.rb, line 159 def remote_ip @remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s end
由于领导跟外面公司合作用了某某的加速服务(网站缓存到了其他地方的服务器上),造成ip获取产生了问题,服务商跟我说他们的真实ip放在了http头的 HTTP_X_REAL_FORWARDED_FOR中,于是打算重新给request写一个方法,获取用户的真实ip。
# 增加代理之后,ip发生了变化,需要取原始的ip地址 class ActionController::Request def real_ip !@env['HTTP_X_REAL_FORWARDED_FOR'].blank? ? @env['HTTP_X_REAL_FORWARDED_FOR'] : remote_ip end end