Logging IP addresses of people who access the shiny-server?

4,039 views
Skip to first unread message

Susan Vanderplas

unread,
Apr 5, 2013, 12:16:17 PM4/5/13
to shiny-...@googlegroups.com
I'm looking to use Shiny to conduct research using Amazon Mechanical Turk, and one of the ways we have previously identified multiple submissions from the same user is to record IP addresses. I know that this is possible in JavaScript, but I have no idea how to interface with JS using Shiny (I've read the tutorial, but that seems to be much more focused on modifying the webpage, which is really outside the scope of what I would like to do). Is there an easier way that doesn't involve learning JavaScript just to get this particular bit of data? Has anyone ever tried to do something similar before?

Thanks!

Joe Cheng

unread,
Apr 5, 2013, 2:02:29 PM4/5/13
to shiny-...@googlegroups.com
You can use the access_log configuration directive to store a list of all HTTP requests made on your Shiny Server. But I don't think that's what you're asking for, is it? You probably want to access the IP address from inside of your server function. In that case, it's not currently possible (without JavaScript, which would be fairly easy to spoof) but I've filed a bug for it.


On Fri, Apr 5, 2013 at 9:16 AM, Susan Vanderplas <srvand...@gmail.com> wrote:
I'm looking to use Shiny to conduct research using Amazon Mechanical Turk, and one of the ways we have previously identified multiple submissions from the same user is to record IP addresses. I know that this is possible in JavaScript, but I have no idea how to interface with JS using Shiny (I've read the tutorial, but that seems to be much more focused on modifying the webpage, which is really outside the scope of what I would like to do). Is there an easier way that doesn't involve learning JavaScript just to get this particular bit of data? Has anyone ever tried to do something similar before?

Thanks!

--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Susan Vanderplas

unread,
Apr 5, 2013, 6:16:01 PM4/5/13
to shiny-...@googlegroups.com
I would like to access the IP address from inside the server function, yes. I found a couple of functions that are supposed to grab the IP using JavaScript - how would I go about accessing that data from R, and where would the functions need to be located? 

Michele Carriero

unread,
Jun 17, 2013, 12:40:20 PM6/17/13
to shiny-...@googlegroups.com
HI, 

I guess you mean the public address. I have some web app running locally (with Rook) and need to get the network ip of the clients. In my current web server seems not possible to achieve. Would Shine allow this?

Susan Vander Plas

unread,
Jun 17, 2013, 12:49:52 PM6/17/13
to shiny-...@googlegroups.com
I got it to work using a couple of tricks. In ui.R, 


inputIp <- function(inputId, value=''){
  tagList(
    singleton(tags$head(tags$script(src = "js/md5.js", type='text/javascript'))),
    singleton(tags$head(tags$script(src = "js/shinyBindings.js", type='text/javascript'))),
    tags$body(onload="setvalues()"),
    tags$input(id = inputId, class = "ipaddr", value=as.character(value), type="text", style="display:none;")
  )
}

and then in your shinyUI() call, you just need
 inputIp("ipid")
somewhere.

Basically, I created a hidden text input field that the javascript file can write to. Javascript gets the IP address from another service (running PHP, I think). This set of functions is located in another file, which I've named shinyBindings.js. (Remember to put this in the /Appname/www/js/ folder when you deploy your app...)

/*
 * Set the uid fingerprint into the DOM elements that need to know about it.
 * Do not call before the form loads, or the selectors won't find anything.
 */
var inputIpBinding = new Shiny.InputBinding();
$.extend(inputIpBinding, {
  find: function(scope) {
    return $.find('.ipaddr');
  },
  getValue: function(el) {
    return $(el).val();
  },
  setValue: function(el, values) {
    $(el).attr("value", getip())
    $(el).trigger("change");
  },
  subscribe: function(el, callback) {
    $(el).on("change.inputIpBinding", function(e) {
      callback();
    });
  },
  unsubscribe: function(el) {
    $(el).off(".inputIpBinding");
  }
});
Shiny.inputBindings.register(inputIpBinding);

function getip() {
ip = null;
$.getJSON("http://jsonip.com?callback=?",
  function(data){
       ip = data.ip;
       callback(ip);
       $(".ipaddr").attr("value", ip);
       $(".ipaddr").trigger("change");
 //return ip address correctly
  });
//alert(ip); //undefined or null
}
function callback(tempip)
{
ip=tempip;
// alert(ip); //undefined or null
}


This does depend on the service http://jsonip.com?callback=?, but it's been reasonably dependable for me...


On Mon, Jun 17, 2013 at 11:40 AM, Michele Carriero <carrier...@gmail.com> wrote:
HI, 

I guess you mean the public address. I have some web app running locally (with Rook) and need to get the network ip of the clients. In my current web server seems not possible to achieve. Would Shine allow this?

--
You received this message because you are subscribed to a topic in the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/shiny-discuss/EGQhEyoEk3E/unsubscribe.

To unsubscribe from this group and all its topics, send an email to shiny-discus...@googlegroups.com.

Michele

unread,
Jun 23, 2013, 5:41:29 AM6/23/13
to shiny-...@googlegroups.com
I've found that Node allows you to get this info with

var connect = require('connect');
var app = connect();
// setup the query middleware
app.use(connect.query());

Since shiny is based on Node.js. Why we can't access the Node functionalities?
Thanks

Michele

unread,
Jun 23, 2013, 5:47:23 AM6/23/13
to shiny-...@googlegroups.com
Hi Susan,

thanks for that. Nice method, but in my case the apps run locally and I think your function getip() will return the public one which I don't really need.

Besides, I have tried the access_log but it remains blank. My .conf file is:

run_as shiny;

server {
  listen 3838;

  location / {
    site_dir /var/shiny-server/www;
    log_dir /var/shiny-server/log;
    directory_index on;
  }

}

access_log /home/michelec/log.log;

thanks for your help!

Michele

Huang Jianhua

unread,
Jul 19, 2013, 8:37:30 PM7/19/13
to shiny-...@googlegroups.com
Hi Susan:

Can you please give an example for this. I tried to put what you described into my ui.R, but I can't figure out the exact location for these codes. I appreciate it if you can provide a simple example. Thanks.

Joshua

Susan Vander Plas

unread,
Jul 21, 2013, 3:01:19 PM7/21/13
to shiny-...@googlegroups.com
Sorry it took me so long to be able to respond. https://gist.github.com/srvanderplas/6049567 has the relevant code.

Huang Jianhua

unread,
Jul 22, 2013, 2:15:46 PM7/22/13
to shiny-...@googlegroups.com
Thanks, Susan. I will try it out whether it works. 

Claude Boivin

unread,
Jan 29, 2014, 5:54:51 PM1/29/14
to shiny-...@googlegroups.com
I just tried it. It works well.
Thank's a lot for this great work.
Reply all
Reply to author
Forward
0 new messages