Capturing IP address from a form - ruby-on-rails

I have a rails form and am trying to capture a client's IP address and ultimately convert that into a zip code. I've done the following:
Controller
def create
...
begin
response = open('https://jsonip.com/').read
data = JSON.parse(response)
ip_address = data['ip']
ip_type = 'jsonip'
rescue
ip_type = 'request.remote_ip'
ip_address = request.remote_ip
end
if ip_address
zip = Geocoder.search(ip_address)
p "IP Address (#{ip_type}): #{ip_address}, zip: #{zip}"
#potential_client.zip_code = zip.first.try(:postal) if zip.present?
end
...
end
This code came from here because request.remote_ip kept returning the same IP address. It seemed to work but once I push to Heroku, it seems like everyone is still coming from the same IP address.
What else am I missing?

With the call to jsonip.com, that is your server rendering and requesting that page so it makes sense that the server IP is returned.
With Heroku and other SaaS providers the remote IP will return the IP of the server or load balancer. Heroku does provide a header "x-forwarded-for" that has a list of IPs the request has passed through.

Related

Rails request.ip or request.remote_ip return different value

When I store IP of client using req.ip and req.remote_ip then it showing different result when request twice using same device and internet connection.
for first req it returns:-
2402:8100:3092:16f4:1:1:cd28:307f
for second request it returns
27.97.134.92
which is ipv4.
Is there any way to get either only ipv6 or only ipv4 address?

running a link through localhost on a live page

I have an external program running a local API that is set up to play wav files when an endpoint is hit.
In my development environment, it works fine, but when I push to live environment it doesn't work any longer.
Am i missing something?
thanks!
JqueryController
def playfile
require 'json'
HTTParty.get("http://192.168.1.161:5000/play/98")
response = HTTParty.get("http://192.168.1.161:5000/play/#{params[:id]}")
parsed = JSON.parse(response)
#message = params[:message]
Hint.first.update_attributes(message:#message)
if parsed['success'] == true
#success = "Success"
else
#success = "Failed"
end
end
The View
=form_tag("/jquery/playfile", method: 'post', remote:true) do
= label_tag 'hints on the tv!'
= hidden_field_tag :id , 39
=render 'layouts/play'
When I hit the endpoint .. googles inspector is showing a 'pending' request, which eventually dies, and returns an application error response (from heroku)
Im guessing it has something to do with not being allowed to hit a localhost address from a live site..is there a way to get around this?
You cannot access your LAN from the internet (heroku).
If you make a GET on http://192.168.1.161:5000/play/98heroku will search in its own network..
Solution 1:
make a link ().
If you then hit that link from your LAN this would work. (you can use redirect_back if you want to redirect to back to the production site).
Solution 2:
make a tunnel from your http://192.168.1.161:5000/play/98 device.
You can do this with ngrok for example.
Then you would be able to make a GET request with HTTP Party from heroku.
HTTParty.get("http://<ngrok-hash>.ngrok.com/play/98")
NOTE: you need to have a running server on http://192.168.1.161:5000/play/98 for both solutions

Advice on how to set up a connection between nancy service and server

I am working on a project whereby we have sites (developed with ruby on rails) hosted on an Ubuntu server using tomcat. We want these sites to make HTTP calls to a service developed using Nancy. We have this working locally whereby the service is hosted on a machine that we can call within our network. We cannot however get it working when live. Here is an example call:
def get_call(routePath)
started_at = Time.now
enc_url = URI.encode("#{settings.service_endpoint}#{routePath}")
uri = URI.parse(enc_url)
http = Net::HTTP.new(uri.host, uri.port)
req = Net::HTTP::Get.new(uri.request_uri)
resp = http.request(req)
logger.bench 'SERVICE - GET', started_at, routePath
return resp if response_ok?(resp)
end
When working locally the settings are as follows:
settings.service_endpoint = http://10.10.10.27:7820
routePath = /Customers
When we upload it to the server we use the following:
settings.service_endpoint = http://127.0.0.1:24099
routePath = /Customers
We currently get the following error:
SocketError at /register
initialize: name or service not know
with the following line being highlighted:
resp = http.request(req)
Are we completely wrong with the IP being called. Should it be 127.0.0.1, localhost. 10.10.10.27 or something entirely different? The strange thing is we can do a GET call via telnet in our Ubuntu server (telnet 127.0.0.1 24099) so that must mean the server can make the calls but the site hosted on the server cannot. Do we need to include a HTTP proxy (have read some reference to that but dont really know if its needed).
Apologies if its obvious but we have never tried anything like this before so its all very perplexing. Any further information required just let me know.
We changed the service_endpoint to localhost and it worked. Not sure if this is because it didnt like "http://" or some other reason. Any explanation as to why this is the case would be much appreciated, just so we know. Thanks!

How to use $remote_addr with rails and nginx secure_link

I have a rails application that makes calls to another server via net::http to retrieve documents.
I have set up Nginx with secure_link.
The nginx config has
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$secure_link_expires$uri$remote_addr mySecretCode";
On the client side (which is in fact my rails server) I have to create the secure url something like:
time = (Time.now + 5.minute).to_i
hmac = Digest::MD5.base64digest("#{time}/#{file_path}#{IP_ADDRESS} mySecretCode").tr("+/","-_").gsub("==",'')
return "#{DOCUMENT_BASE_URL}/#{file_path}?md5=#{hmac}&expires=#{time}"
What I want to know is the best way to get the value above for IP_ADDRESS
There are multiple answers in SO on how to get the ip address but alot of them do not seem as reliable as actually making a request to a web service that returns the ip address of the request as this is what the nginx secure link will see (we don't want some sort of localhost address).
I put the following method on my staging server:
def get_client_ip
data=Hash.new
begin
data[:ip_address]=request.ip
data[:error]=nil
rescue Exception =>ex
data[:error]=ex.message
end
render :json=>data
end
I then called the method from the requesting server:
response = Net::HTTP.get_response(URI("myserver.com/web_service/get_client_ip"))
if response.class==Net::HTTPOK
response_hash=JSON.parse response.body
ip=response_hash["ip_address"] unless response_hash[:error]
else
#deal with error
end
After getting the ip address successfully I just cached it and did not keep on calling the web service method.

Get own IP address

How to get my own IP address with Rails?
When I do it like this I got: 127.0.0.1
#ip = request.remote_ip
Is there any way to get the Public IP?
Try:
require 'socket'
ip=Socket.ip_address_list.detect{|intf| intf.ipv4_private?}
ip.ip_address if ip
I believe request.env['SERVER_NAME'] works, if you want to reflect the server base address back
Call the page using your IP, not localhost. I.e, 192.168.2.9:3000 in case of the default development environment would yield:
request.env['REMOTE_ADDR']
#=> 192.168.2.9
or:
request.remote_ip
#=> 192.168.2.9
As your request is local to the server, it returns the "localhost" address, i.e. 127.0.0.1.
If you request it from a machine hosted on the internet, it will give you a static IP of the remote server.
If you want the static IP of own internet then visit http://ping.eu and you can see your public IP.
Try this:
request.env['REMOTE_ADDR']
This does not answer this question. I think someone else can find this answer helpful.
Problem:
I am developing a mobile app. So, When I debug/hot reload/live reload the app in real mobile device. Images url does not work with localhost:3000.
Images works with ip like this: http://192.168.0.102:3000/user/1/profile-223hfkj33.jpg
Problem is Every time I turn on laptop and connect to wifi router, laptop ip changes. So, every-time I need to change asset_host in environments/development.rb file.
Looking at previous answers I found a solution:
Solution:
in environments/development.rb I write this code:
server_address = "#{Socket.ip_address_list.detect(&:ipv4_private?).try(:ip_address)}:3000"
config.asset_host = server_address
puts "Server address: #{server_address}"
# when I run `rails s`, this line prints server address in console
So, It sets asset_host like this: 192.168.0.102:3000
And when I turn on laptop, laptop gets new ip address and it works.

Resources