I'm attempting to retrieve a cookie from a user's browser in a shiny app to produce a different UI for different users. To work with cookie sin R shiny, I've followed this tutorial and I've extended shinyjs with the following javascript code:
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", "");
}
I'm also using attempting to set and get the cookie within a R Shiny module, which may be significant.
I'm able to set the cookie from within the module, I can verify this from my browser; however, when I try and get the cookie, I consistently get NULL.
I call the module in server.R like this:
user_auth_return <- observe({
callModule(
user_auth_module,
"user_auth"
)
})
And here is the module itself:
user_auth_module <- function(input, output, session) {
print("1")
# Initializing reactive values.
values <- reactiveValues(
passwords = data.frame(matrix(nrow = 0, ncol = 2)),
cookies = data.frame(matrix(nrow = 0, ncol = 2)),
cookies.match = FALSE,
user = NULL,
password.error = FALSE
)
# Setting new cookie.
observeEvent(input$login, {
print("5")
# Reading in pasword table.
try(values$passwords <- read.csv("data/passwords.csv", header = FALSE, quote = "", stringsAsFactors = FALSE))
# Checking if match exists for username-password pair.
if (input$username != "" &&
input$username %in% values$passwords[, 1] &&
checkpw(input$password, hash = values$passwords[values$passwords[, 1] == input$username, 2])) {
print("6")
# Creating random session ID.
sessionid <- paste(
collapse = '',
sample(x = c(letters, LETTERS, 0:9), size = 64, replace = TRUE)
)
sessionid <- "cookie123"
# Setting new cookie to session ID.
print("setting cookie")
js$setcookie(sessionid)
# Updating user cookie if already present, otherwise, creating new username-cookie pair.
if (input$username %in% values$cookies[, 1]) {
print("7")
values$cookies[values$cookies[, 1] == input$username, 2] <- sessionid
} else {
print("8")
values$cookies <- rbind(values$cookies, c(input$username, sessionid))
}
# Writing updated cookie data frame to data file.
write.table(values$cookies, file = "data/cookies.csv", quote = FALSE, sep = ",", row.names = FALSE, col.names = FALSE)
} else {
print("9")
values$password.error <- TRUE
}
})
# Checking if match exists for cookie.
observe({
# Check cookies when input is pressed.
input$login
# Reading in cookie table.
try(values$cookies <- read.csv("data/cookies.csv", header = FALSE, quote = "", stringsAsFactors = FALSE))
# Getting cookie.
js$getcookie()
print("user")
print(input$jscookie)
print("database")
print(values$cookies[, 2])
# Checking if match exists for cookie.
if (!is.null(input$jscookie) &&
input$jscookie %in% values$cookies[, 2]) {
print("3")
values$cookies.match <- TRUE
values$user <- values$cookies[values$cookies[, 2] == input$jscookie, 1]
} else {
print("4")
values$cookies.match <- FALSE
}
})
# Toggling password error message if username/password combination is not found.
observe({
print("10")
toggleState("password.error.message", condition = values$password.error)
})
# Toggling between login and logout tab if cookie is present.
observeEvent(values$cookie.match, {
print("11")
hide("login_page")
show("logout_page", anim = TRUE, animType = "fade")
})
# Remove user cookie at logout.
observeEvent(input$logout, {
print("12")
js$rmcookie()
})
# Returning login status.
return("return")#values$cookies.match)
}
When I run the module I get the following numbers, showing progression through the program at each print statement:
[1] "1"
[1] "user"
NULL
[1] "database"
[1] "cookie123"
[1] "4"
[1] "10"
And after entering the correct password:
[1] "5"
[1] "6"
[1] "setting cookie"
[1] "7"
[1] "user"
NULL
[1] "database"
[1] "cookie123"
[1] "4"
Any help is appreciated.
EDIT:
I've since found that I am able to retrieve the cookie from server.R using this code:
observe({
js$getcookie()
print("server cookie")
print(input$jscookie)
})
Because I still can't access the cookie using the same code in the module, I think that I've narrowed down my issue to the variable input$jscookie
. Would I have to get this value in a different way in a Shiny module compared to on a Shiny server?