Robert's Data Science Blog

Reuse Credentials with httr

When using the httr package for accessing REST endpoints, it is sometimes necessary to authenticate:

response <- httr::GET(
	"<url>",
	httr::authenticate("<user>", "<password>")
)

(At least) on Windows it is possible to use the logged in user credentials for authenticate without actually writing them. The trick is to use : as both user and password and any as the type of authentication (ntlm may also work):

response <- httr::GET(
	"<url>",
	httr::authenticate(":", ":", "any")
)

I have not been able to find any documentation about this, but it works!

When running on My Machine(TM) this works for web pages where I have access. But sometimes it is useful to use other credentials without changing the code, e.g. when testing on another machine or running code by a service.

One approach is to set environment variables that R can access. Either as system environment variables or in a .Renviron file with the following content

user = "<user>"
password = "<password>"

We can access these variables in the REST call:

response <- httr::GET(
	"<url>",
	httr::authenticate(
		user = Sys.getenv("user", unset = ":"), 
		password = Sys.getenv("password", unset = ":"), 
		type = "any"
	)
)

If user and password are available as environment variables the parameters user and password are replaced with these values; otherwise they are both :.

Load variables once

The above solution works, but maybe it’s cumbersome to access these environment variables at every authentication. If the code goes into an R package there is also the possibility of loading the values once into the options in R.

Inspired by how Hadley Wickham handles options in devtools the following code in R/zzz.R will do just that:

.onLoad <- function(libname, pkgname) {
	op <- options()
	
	op.pkg <- list(
	    pkg.user = Sys.getenv("user", unset = ":")
	    pkg.password = Sys.getenv("password", unset = ":")
	)
	
	toset <- !(names(op.pkg) %in% names(op))
	if(any(toset)) 
	    options(op.pkg[toset])
	
	invisible()
}

Now the user and password can be obtained with getOption("pkg.user") and getOption("pkg.password").