What's the difference between request.remote_ip and request.ip in Rails?
From source:
module ActionDispatch
class Request < Rack::Request
# ...
def ip
@ip ||= super
end
def remote_ip
@remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s
end
# ...
end
end
where Rack::Request looks like this
module Rack
class Request
def ip
remote_addrs = split_ip_addresses(@env['REMOTE_ADDR'])
remote_addrs = reject_trusted_ip_addresses(remote_addrs)
return remote_addrs.first if remote_addrs.any?
forwarded_ips = split_ip_addresses(@env['HTTP_X_FORWARDED_FOR'])
if client_ip = @env['HTTP_CLIENT_IP']
# If forwarded_ips doesn't include the client_ip, it might be an
# ip spoofing attempt, so we ignore HTTP_CLIENT_IP
return client_ip if forwarded_ips.include?(client_ip)
end
return reject_trusted_ip_addresses(forwarded_ips).last || @env["REMOTE_ADDR"]
end
end
end
So remote_ip
gives precedence to action_dispatch.remote_ip
. That is being set by ActionDispatch::RemoteIp
middleware. You can see in that middleware's source that it's checking for spoofing attacks when being called, since it's calling GetIp.new
to set that env variable. That's needed since remote_ip
reads the ip address even through the local proxies, as Clowerweb explains.
Rails ActionController: Difference between request.remote_ip and request.remote_addr
I'm the author of the current implementation of remote_ip
, and the other things that it does include checking for IP spoofing attacks, and correctly handling multiple X-Forwarded-For
headers. There's a big caveat, though: only some Ruby web servers support multiple headers, so the value still might be wrong.
I wrote up the results from testing the most popular Ruby app servers on my blog, which you might want to check out if repeated headers matter for your application.
Rails - difference between request.env['HTTP_X_FORWARDED_FOR'] and request.remote_ip
Generally, you should use request.remote_ip
. It is a method introduced by Rails which tries to gather the actual remote IP of the connection using various means, including evaluating request.env['HTTP_X_FORWARDED_FOR']
where appropriate.
In the end, the IP returned by request.remote_ip
is calculated in the ActionDispatch::RemoteIp middleware. This is a good bit more generic than trying to gather the IP yourself as it takes proxy stages into account which can set various HTTP headers.
How do I get a client's ip address in Rails?
This looks like code that should be in a model, so I'm assuming that's where this method is. If so, you can't (at least 'out of the box') access the request object from your model as it originates from an HTTP request -- this is also why you get "undefined local variable or method "request" from main" in your console.
If this method is not already in your model I would place it there, then call it from you controller and pass in request.remote_ip as an argument.
def get_location_users(the_ip)
if current_user
return current_user.location_users
else
l = Location.find_by_ip(the_ip)
lu = LocationUser.new({:location_id => l.id, :radius => Setting.get("default_radius").to_i})
return [lu]
end
end
Then, in your controller ::
SomeModel.get_location_users(request.remote_ip)
Also, be aware that "Location.find_by_ip" will return nil if no records are matched.
And, you can issue a request in your console by using app.get "some-url", then you can access the request_ip from request object app.request.remote_ip and use it for testing if needed.
Need help get access to get remote_ip from a model
You can do the following for getting the remote ip of the client, this is using a controller.
class TestsController < ApplicationController
def get_ip
ip = request.remote_ip
Test.use_ip(ip)
end
end
Assuming you have a model. I'm assuming it as Test
class Test < ActiveRecord::Base
def self.use_ip(ip)
puts ip
end
end
As per your requirement, which is going against convention of Rails (which is not a very good practice)
define the following in application_controller.rb
before_filter :pass_request_around
def pass_request_around
Thread.current[:request] = request
end
In model, request object should be available now
def get_ip
request = Thread.current[:request]
ip = request.remote_ip
end
Difference Between Remote IP Addresses And Physical Addresses
They are the address used at two different level.
IP is a software virtual name assigned to a machine.
Physical address (if you mean MAC with this) is a unique code that belong to a comunication interface.
Physical address is used at a lower level to physically route the message.
Reference to OSI model: OSI
Change value of request.remote_ip in Ruby on Rails
If you want this functionality in your whole application, it might be better/easier to override the remote_ip method in your app/helpers/application_helper.rb
:
class ActionDispatch::Request #rails 2: ActionController::Request
def remote_ip
'1.2.3.4'
end
end
And the 1.2.3.4 address is available everywhere
Related Topics
How to Debug Http of Ruby Google-Api-Client
How to Input Integer Value to an Array, Based Preceeding Row + Column Values
Strip Signatures and Replies from Emails
Rails: Good Rspec2 Example Usage? (Also: Cucumber, Pickle, Capybara)
How to Convert a JSON Formatted Key Value Pair to Ruby Hash with Symbol as Key
Rails: How to Access Restful Helpers
Ruby: How to Define a Class Method in a Module
Ruby/Rails CSV Parsing, Invalid Byte Sequence in Utf-8
Implementation of "Remember Me" in a Rails Application
Rails: Money Gem Converts All Amounts to Zero
How to Call Java API from Ruby 1.8 or 1.9
Replacing Text in One CSV Column Using Fastercsv
How to Log Every Method That's Called in a Ruby Program
What's the Difference Between Request.Remote_Ip and Request.Ip in Rails
How to Customize Gemfile Per Developer
Rails: How to Make Date Strftime Aware of the Default Locale