not should but must. in my experience security measures are not adopted even IF easy.
1https://www.rplumber.io/docs/security.html
verifying an identity
Image by Andreas Lischka from Pixabay
--> plumber API: check credentials (e.g. login)
verifying an identity
Image by Andreas Lischka from Pixabay
--> plumber API: check credentials (e.g. login)
verifying access rights / permissions to do something
Image by Nina Garman from Pixabay
--> plumber API: checking permissions to access endpoint(s) xyz
The goal of sealr is to provide multiple authentication and authorization strategies for plumber by using filters. In doing so, we hope to make best practices in authentication easy to implement for the R community.1

FacebookStrategy
FacebookStrategy passport.authenticate(), e.g. passport.authenticate('facebook') to authenticate calls to endpoints
Ever wanted to have R Memes at the ready whenever you want? Of course not. But here is a package that does exactly that.
pr$handle("POST", "/authentication", function (req, res, user = NULL, password = NULL) { # check if user provided credentials if (is.null(user) || is.null(password)) { res$status <- 404 return(sealr::is_authed_return_list(FALSE, "Failed.", 404, "User or password wrong.")) } # find user in database index <- match(user, users$user) # check if user exist if (is.na(index)) { res$status <- 401 return(sealr::is_authed_return_list(FALSE, "Failed.", 401, "User or password wrong.")) } # check if password is correct if (!bcrypt::checkpw(password, users$password[index])){ res$status <- 401 return(sealr::is_authed_return_list(FALSE, "Failed.", 401, "User or password wrong.")) }
# define jwt payload # information about the additional fields can be found at # https://tools.ietf.org/html/rfc7519#section-4.1 payload <- jose::jwt_claim(userID = users$id[index]) # convert secret to bytes secret_raw <- charToRaw(secret) # encode token using the secret jwt <- jose::jwt_encode_hmac(payload, secret = secret_raw) # return jwt as response return(jwt = jwt)}, preempt = c("auth"))
/meme/<no>/stats, leave /meme unprotected
goal: protect /meme/<no>/stats, leave /meme unprotected
filter(s): "[...] “pipeline” for handling incoming requests."1
goal: protect /meme/<no>/stats, leave /meme unprotected
filter(s): "[...] “pipeline” for handling incoming requests."1
pr$filter("auth", function (req, res) { sealr::authenticate(req = req, # plumber object: the request from the user res = res, # plumber object: the response list is_authed_fun = sealr::is_authed_jwt, # checker fun token_location = "header", secret = secret) # arguments passed to the checker function})
goal: protect /meme/<no>/stats, leave /meme unprotected
filter(s): "[...] “pipeline” for handling incoming requests."1
pr$filter("auth", function (req, res) { sealr::authenticate(req = req, # plumber object: the request from the user res = res, # plumber object: the response list is_authed_fun = sealr::is_authed_jwt, # checker fun token_location = "header", secret = secret) # arguments passed to the checker function})
goal: protect /meme/<no>/stats, leave /meme unprotected
filter(s): "[...] “pipeline” for handling incoming requests."1
pr$filter("auth", function (req, res) { sealr::authenticate(req = req, # plumber object: the request from the user res = res, # plumber object: the response list is_authed_fun = sealr::is_authed_jwt, # checker fun token_location = "header", secret = secret) # arguments passed to the checker function})
1https://www.rplumber.io/docs/routing-and-input.html#filters
pr$handle("GET", "/meme/<no>/stats", function(req, res, no){ no <- as.integer(no) stats <- memes %>% dplyr::filter(meme_number == no) %>% dplyr::slice(1) %>% # make sure only one is returend dplyr::select(meme_number, shares_count, likes_count, comments_count) return(as.list(stats))}, serializer = plumber::serializer_unboxed_json())
pr$handle("GET", "/meme/<no>/stats", function(req, res, no){ no <- as.integer(no) stats <- memes %>% dplyr::filter(meme_number == no) %>% dplyr::slice(1) %>% # make sure only one is returend dplyr::select(meme_number, shares_count, likes_count, comments_count) return(as.list(stats))}, serializer = plumber::serializer_unboxed_json())
pr$handle("GET", "/meme", function(req, res){ # get a random meme random_meme <- memes %>% dplyr::sample_n(1) %>% dplyr::select(meme_number, message, full_picture) return(as.list(random_meme))}, serializer = plumber::serializer_unboxed_json(), preempt = c("auth"))
Keyboard shortcuts
| ↑, ←, Pg Up, k | Go to previous slide |
| ↓, →, Pg Dn, Space, j | Go to next slide |
| Home | Go to first slide |
| End | Go to last slide |
| Number + Return | Go to specific slide |
| b / m / f | Toggle blackout / mirrored / fullscreen mode |
| c | Clone slideshow |
| p | Toggle presenter mode |
| t | Restart the presentation timer |
| ?, h | Toggle this help |
| Esc | Back to slideshow |