Skip to content

Instantly share code, notes, and snippets.

@calligross calligross/app.R
Last active Dec 8, 2019

Embed
What would you like to do?
Shiny Cookie Based Authentication Example, please visit https://calligross.de/post/using-cookie-based-authentication-with-shiny/ for more information.
library(shiny)
library(shinyjs)
if (!dir.exists('www/')) {
dir.create('www')
}
download.file(
url = 'https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js',
destfile = 'www/js.cookie.js'
)
addResourcePath("js", "www")
# This would usually come from your user database. But we want to keep it simple.
password_hash <- bcrypt::hashpw('secret123') # Never store passwords as clear text
sessionid <- "OQGYIrpOvV3KnOpBSPgOhqGxz2dE5A9IpKhP6Dy2kd7xIQhLjwYzskn9mIhRAVHo" # Our not so random sessionid
jsCode <- '
shinyjs.getcookie = function(params) {
var cookie = Cookies.get("id");
if (typeof cookie !== "undefined") {
Shiny.onInputChange("jscookie", cookie);
} else {
var cookie = "";
Shiny.onInputChange("jscookie", cookie);
}
}
shinyjs.setcookie = function(params) {
Cookies.set("id", escape(params), { expires: 0.5 });
Shiny.onInputChange("jscookie", params);
}
shinyjs.rmcookie = function(params) {
Cookies.remove("id");
Shiny.onInputChange("jscookie", "");
}
'
server <- function(input, output) {
status <- reactiveVal(value = NULL)
# check if a cookie is present and matching our super random sessionid
observe({
js$getcookie()
if (!is.null(input$jscookie) && input$jscookie == sessionid) {
status(paste0('in with sessionid ', input$jscookie))
}
else {
status('out')
}
})
observeEvent(input$login, {
if (input$username == 'admin' & bcrypt::checkpw(input$password, hash = password_hash)) {
# generate a sessionid and store it in your database, but we keep it simple in this example...
# sessionid <- paste(collapse = '', sample(x = c(letters, LETTERS, 0:9), size = 64, replace = TRUE))
js$setcookie(sessionid)
} else {
status('out, cause you don\'t know the password secret123 for user admin.')
}
})
observeEvent(input$logout, {
status('out')
js$rmcookie()
})
output$output <- renderText({
paste0('You are logged ', status())}
)
}
ui <- fluidPage(
tags$head(
# you must copy https://raw.githubusercontent.com/js-cookie/js-cookie/master/src/js.cookie.js to www/
tags$script(src = "js/js.cookie.js")
),
useShinyjs(),
extendShinyjs(text = jsCode),
sidebarLayout(
sidebarPanel(
textInput('username', 'User', placeholder = 'admin'),
passwordInput('password', 'Password', placeholder = 'secret123'),
actionButton('login', 'Login'),
actionButton('logout', 'Logout')
),
mainPanel(
verbatimTextOutput('output')
)
)
)
shinyApp(ui = ui, server = server)
@TomWeishaar

This comment has been minimized.

Copy link

TomWeishaar commented Sep 25, 2017

Not only did you show me how to do logins, you introduced me to the Shinyjs package, which has been extremely helpful. Bravo!

@xwydq

This comment has been minimized.

Copy link

xwydq commented Sep 27, 2017

nice!!! man

@Gh0stSG1

This comment has been minimized.

Copy link

Gh0stSG1 commented Jun 2, 2019

Nice work!

In line 10 you set the destination file as: 'js.cookies.js' with:
"destfile = 'www/js.cookies.js'"

In the ui you load the file as "js.cookie.js" (without the s.... cookie instead of cookies). This breaks the example.

@calligross

This comment has been minimized.

Copy link
Owner Author

calligross commented Jun 13, 2019

Thanks, I fixed it.

@markusdumke

This comment has been minimized.

Copy link

markusdumke commented Sep 22, 2019

'https://raw.githubusercontent.com/js-cookie/js-cookie/master/src/js.cookie.js' does not exist anymore. Even when including the old js.cookie.js script it does not work.

Using tags$script(src = "https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js") in the UI instead of tags$script(src = "js/js.cookie.js") seems to work though.

@calligross

This comment has been minimized.

Copy link
Owner Author

calligross commented Oct 5, 2019

Using tags$script(src = "https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js") in the UI instead of tags$script(src = "js/js.cookie.js") seems to work though.

Thanks, I updated the download URL.

@nikhil-nikss

This comment has been minimized.

Copy link

nikhil-nikss commented Dec 2, 2019

When i am running this application i am getting error as cannot open url for cookies download.
Can anyone assist me?

In addition: Warning message:
In download.file(url = "https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js", :
cannot open URL 'https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js': HTTP status was '403 Forbidden'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.