Heroku Geolocation >> Always Returns "Seattle, WA"
In Rails 3, both the geo_ip and the geo_location gems return accurate results on my local machine, but once uploaded to Heroku, persistently returns "Seattle, WA" (I'm located in Pennsylvania).
I did some digging, and found that the H开发者_开发技巧eroku shared database I'm using is located in Seattle. Can anyone point me in the right direction for how to handle this situation? Again, while running locally the geolocation is working as intended.
Thanks!!
If you are using hostname-based SSL on Heroku, there is currently no way to get the request's original IP. See this thread:
http://groups.google.com/group/heroku/browse_thread/thread/8cd2cba55f9aeb19
On that thread, someone mentioned http://jsonip.com/, which does what you'd expect:
ultramarine:~ jdc$ curl http://jsonip.com/
{"ip":"131.247.152.2"}
My plan is to make an Ajax request to jsonip, then pass the IP back to the server and geolocate it using geoip or geokit. I tried it with geoip thusly:
ruby-1.9.2-p136 :004 > c = GeoIP.new('GeoIP.dat').country('131.247.152.2')
=> ["131.247.152.2", "131.247.152.2", 225, "US", "USA", "United States", "NA"]
(It seems like geokit will be easier to deal with because it doesn't require me to manage a .dat file of IP mappings. I expect to end up using that.)
I don't know how heroku works, but you might be behind a load balancer. You'll need to set your TRUSTED_PROXIES
to get request.remote_ip to be the HTTP_X_FORWARDED_FOR
address.
You can check to see if this is your problem by adding an action to one of your controllers like this:
def remote_ip
render :text => "REMOTE_ADDR: %s<br/>remote_ip: %s<br/>HTTP_X_FORWARDED_FOR: %s" %
[ request.env['REMOTE_ADDR'],
request.remote_ip,
request.env['HTTP_X_FORWARDED_FOR'] ]
end
If you've got an HTTP_X_FORWARDED_FOR
, then you need to tell Rails about trusted proxies. Once you do that, your request.remote_ip
and your HTTP_X_FORWARDED_FOR
ips will be the same.
In your production.rb
, add these lines, where the allowed_ips regex includes your load balancer IPs. Replace the a.b.c.
with the load balancer IPs you get from heroku.
# Setup Trusted Proxies
allowed_ips = /^a\.b\.c\.|^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\./i
ActionController::Request.const_set("TRUSTED_PROXIES", allowed_ips)
Interesting. Being a Rails noob, the only thing I can ask is where is it getting the IP from? Is there a way to make sure it is getting it from the user? (Complete rails noob, so you may already be doing this, and I just don't know)
I also found a plugin that seems to be well made called GeoKit. Link: http://geokit.rubyforge.org/ -- Maybe it will work better?
精彩评论