Auth when using R in the browser

If you are working with R in a web-based context, such as RStudio Server, RStudio Cloud, or RStudio Workbench, your experience of browser-based auth flows will be different from those using R on their local machine. You need to use out-of-band authentication, sometimes denoted “oob”. After the usual auth dance, instead of seeing “authentication successful, return to R!”, you are presented with an authorization code to copy and paste back into your R session.

The need to use oob auth can sometimes be detected automatically. For example, oob auth is always used when the httpuv package is not installed. gargle also tries to detect usage via RStudio Server, Cloud, or Workbench, but this still may not catch 100% of situations where oob auth is necessary.

Therefore, some users may still need to recognize this situation and explicitly request oob auth.

Here’s a typical presentation of this problem: during auth, you are redirected to localhost on port 1410 and receive an error along these lines:

Chrome: This site can't be reached; localhost refused to connect.
Firefox: Unable to connect; can't establish a connection.

This is a sign that you need to explicitly request oob auth.

This article describes how to do so in a package that uses gargle for auth, which includes:

Request oob auth in the PKG_auth() call

These packages aim to make auth “just work” for most users, i.e. it’s automatically triggered upon first need. However, it is always possible to initiate auth yourself, which gives you the opportunity to specify non-default values of certain parameters. Here’s how you request oob auth, using googledrive as an example:

library(googledrive)

drive_auth(use_oob = TRUE)

# now carry on with your work
drive_find(n_max = 5)

This code is tailored to an interactive session and assumes that a user is present to respond. If you also need to setup a token for non-interactive use, see the article Non-interactive auth. A key point is that oob auth is relevant to how you initially obtain a token. It is orthogonal to downstream use and refreshing. So it is possible that you need to attend to both!

Set the gargle_oob_default option

If you know that you always want to use oob auth, as a user or within a project, the best way to express this is to set the gargle_oob_default option.

options(gargle_oob_default = TRUE)

This code could appear at the top of a script, in a setup chunk for .Rmd, or in a Shiny app. But it probably makes even more sense in a .Rprofile startup file, at the user- or project-level.

Once that option has been set, it is honoured by downstream calls to PKG_auth(), explicit or implicit, because the default behaviour of use_oob is to consult the option:

drive_auth <- function(email = gargle::gargle_oauth_email(),
                       path = NULL,
                       scopes = "https://www.googleapis.com/auth/drive",
                       cache = gargle::gargle_oauth_cache(),
                       use_oob = gargle::gargle_oob_default(),
                       token = NULL) {...}

But I didn’t need oob yesterday!

Sometimes the usual oauth web flow suddenly stops working for people working directly with R (so NOT via the browser) and they use oob auth to get unstuck again. What’s going on in this case?

The initial error looks something like this:

createTcpServer: address already in use
Error in httpuv::startServer(use$host, use$port, list(call = listen)) : 
  Failed to create server

It’s characteristic of some other process sitting on port 1410, which is what httr is trying to use for auth.

It’s true that using oob auth is a workaround. But oob auth is, frankly, more clunky, so why use if you don’t have to? Here are ways to fix.

On *nix-y systems, use lsof to get the process ID:

sudo lsof -i :1410

The output will look something like this:

COMMAND   PID  USER   FD   TYPE            DEVICE SIZE/OFF NODE NAME
R       16664 jenny   20u  IPv4 0x63761a50856c65f      0t0  TCP localhost:hiq (LISTEN)

In this case, as is typical, this is a zombie R process and I feel confident killing it. The process ID is listed there as PID. Note that and kill the process, like so, filling in the PID you found:

kill -9 <PID>

So, to be clear, in this example, the command would be:

kill -9 16664

The normal, non-oob auth web flow should work again now.

Further reading

Generating OAuth tokens for a server using httr covers some of the same ground, although for the httr package. gargle provides a Google-specific interface to httr. gargle first consults the gargle_oob_default option and, if that is undefined, also consults the httr_oob_default option.

If you’re creating content to be deployed (for example on shinyapps.io or RStudio Connect), you will also need to consider how the deployed content will authenticate non-interactively.