In Rails, what's the best way t开发者_开发问答o get the ip address of the client connecting to the server?
Here are two ways I've found:
request.remote_ip
request.env['HTTP_X_REAL_IP']
I would just use the request.remote_ip
that's simple and it works. Any reason you need another method?
See: Get real IP address in local Rails development environment for some other things you can do with client server ip's.
request.remote_ip
is an interpretation of all the available IP address information and it will make a best-guess. If you access the variables directly you assume responsibility for testing them in the correct precedence order. Proxies introduce a number of headers that create environment variables with different names.
Get client ip using command:
request.remote_ip
I found request.env['HTTP_X_FORWARDED_FOR']
very useful too in cases when request.remote_ip
returns 127.0.0.1
For anyone interested and using a newer rails and the Devise gem: Devise's "trackable" option includes a column for current/last_sign_in_ip in the users table.
From Mozilla docs:
When a client connects directly to a server, the client's IP address is sent to the server (and is often written to server access logs). But if a client connection passes through any forward or reverse proxies, the server only sees the final proxy's IP address, which is often of little use. That's especially true if the final proxy is a load balancer which is part of the same installation as the server. So, to provide a more-useful client IP address to the server, the X-Forwarded-For request header is used.
remote_ip will actually check a handful of headers passed in. This includes both REMOTE_ADDR
and X-Forwarded-For
. X-Forwarded-For
is used in case of a proxy. But REMOTE_ADDR
is checked first. You can verify this in a rspec test:
describe CustomersController, type: :controller do
describe "GET search" do
it "returns a 200" do
whitelisted_ip = '73.1.193.230' # a comcast ip address
request.headers['REMOTE_ADDR'] = whitelisted_ip
request.headers['X-Forwarded-For'] = whitelisted_ip
get :index
expect(response).to have_http_status(:ok)
end
end
end
Inside the controller:
before_action :verify_source_ip, only: [:index]
def verify_source_ip
head(403) unless request.remote_ip == '73.1.193.230'
end
精彩评论