You can now use Polished Authentication to secure your Plumber APIs. Make sure to install the dev version of Polished to try it out.
# install the dev version of polished
remotes::install_github("tychobra/polished")
To add Polished Auth to a Plumber API, first, configure Polished, then add the polished::auth_filter()
filter at the
top of your Plumber API script.
# configure polished
polished::polished_config(
api_key = "your polished API key",
app_name = "your app/API name"
)
#' @filter auth
polished::auth_filter()
That's it. All endpoints below the above filter will require authentication.
If the request is authenticated,
the auth_filter()
attaches a polished_session
list to the request. The
polished_session
can then be used in subsequent filters and endpoints to identify the user
and apply granular access controls to your API endpoints and data. The following is a
working request sent to a minimal Polished Plumber API. You should be able to run the following
code in your own R console to test it out.
api_url <- "https://polished-plumber-demo-amai4lhqja-ue.a.run.app/hi"
r <- httr::POST(
api_url,
httr::authenticate(
user = "demo@tychobra.com",
password = "polished"
)
)
httr::status_code(r)
#> [1] 200
rc <- httr::content(r)
print(rc)
#> $user_uid
#> [1] "d629f5df-50ba-40a2-9c02-375f803693bc"
#>
#> $email
#> [1] "demo@tychobra.com"
#>
#> $email_verified
#> [1] TRUE
#>
#> $is_admin
#> [1] FALSE
#>
#> $hashed_cookie
#> [1] "1b0d9fd78403cc099e97fa6974805602"
#>
#> $two_fa_verified
#> [1] FALSE
#>
#> $session_uid
#> [1] "ea635449-51a7-49e8-9b56-1df2d472169f"
#>
#> $signed_in_as
#> NULL
#>
#> $roles
#> NULL
This simple API is designed to return the polished_session
if
the request is successfully authenticated. Since the request was successful, you
can see the polished_session
list printed to the R console. If authentication had failed, it would have returned an error.
The backend Plumber API code for this minimal working API can be found here.
polished::auth_filter()
supports basic authentication and/or cookie based authentication.
The default is to attempt basic authentication first, and, if the authentication header is not set, fall back to
cookie based authentication. You can adjust the method
argument of polished::auth_filter()
to support only basic auth or only cookie auth. In the above example we
used the default; basic auth, but cookie auth was available as a fallback.
Subsequent requests could continue using basic auth, or, since the user is now signed in, we can use cookie based authentication. e.g.
r2 <- httr::POST(
api_url,
httr::set_cookies(
polished = rc$hashed_cookie
)
)
httr::status_code(r2)
#> [1] 200
rc2 <- httr::content(r2)
print(rc2)
#> $user_uid
#> [1] "d629f5df-50ba-40a2-9c02-375f803693bc"
#>
#> $email
#> [1] "demo@tychobra.com"
#>
#> $email_verified
#> [1] TRUE
#>
#> $is_admin
#> [1] FALSE
#>
#> $hashed_cookie
#> [1] "1b0d9fd78403cc099e97fa6974805602"
#>
#> $two_fa_verified
#> [1] FALSE
#>
#> $session_uid
#> [1] "ea635449-51a7-49e8-9b56-1df2d472169f"
#>
#> $signed_in_as
#> NULL
#>
#> $roles
#> NULL
Note: If you want to accept cookie based authentication requests directly from the browser, you will need to configure your API CORS policy to allow requests from your website's domain. You can enable CORS in a Plumber API with the following filter:
#' @filter cors
function(req, res) {
res$setHeader("Access-Control-Allow-Credentials", "true")
res$setHeader("Access-Control-Allow-Origin", "http://localhost:3000")
if (req$REQUEST_METHOD == "OPTIONS") {
res$setHeader("Access-Control-Allow-Methods","*")
res$setHeader("Access-Control-Allow-Headers", req$HTTP_ACCESS_CONTROL_REQUEST_HEADERS)
res$status <- 200
return(list())
} else {
plumber::forward()
}
}
Place this cors filter above the polished::auth_filter()
in your API code. Make sure to
replace "http://localhost:3000" in the cors filter above with your website's domain name. You should then
be able to send javascript requests to your Plumber API directly from your user's web browser.
We are planning a new polished CRAN realease in the next couple of weeks, so please reach out if you have ideas or requests that you would like to see in the official CRAN release.