I want to use the shinymanager package to secure my Rshiny application but I want to use it with a PostgreSQL database...
I checked the example provided in the documentation and the github of the package to eventually create this code that is not working but I don't know why:
library(RPostgreSQL)
library(shiny)
library(shinymanager)
library(DBI)
library(pool)
library(sodium)
dbname = ***********
host = ***********
user = ***********
password = ***********
con <- dbPool(
drv = dbDriver("PostgreSQL"),
dbname = dbname ,
host = host,
user = user,
password = password )
DBI::dbWriteTable(con, c("test", "test2"), data.frame(
user = c("David"),
password = sodium::password_store("123"),
stringsAsFactors = FALSE
))
my_custom_check_creds <- function(dbname, host, user, password) {
function(user, password) {
con <- dbConnect(drv = dbDriver("PostgreSQL"),
dbname = dbname,
host = host,
user = user,
password = password)
req <- sqlInterpolate(con, sql = "SELECT * FROM test.test2 WHERE test2.user = ({user}) AND test2.password = ({password})",
user = user, password = password)
res <- dbGetQuery(con, statement = req)
if (nrow(res) > 0) {
hashed_password <- res$password
if (sodium::password_verify(hashed_password, password)) {
list(user = user, password = password, result = TRUE)
} else {
list(result = FALSE)
}
} else {
list(result = FALSE)
}
}
}
ui <- fluidPage(
tags$h2("My secure application"),
verbatimTextOutput("auth_output")
)
ui <- secure_app(ui)
server <- function(input, output, session) {
res_auth <- secure_server(
check_credentials = my_custom_check_creds
)
output$auth_output <- renderPrint({
reactiveValuesToList(res_auth)
})
}
shinyApp(ui, server)
The app is launched but after pressing the log in button the app disconnect and I get a not very informating warning message:
��m)
[No stack trace available]
Ok, I haven't tested this at all, since I don't have a Postgres server available at the moment, but I've made some adjustments that should hopefully get you closer to a solution.
Note that your database login and password will be (or certainly should be) different than a random users credentials, so they need to be given different argument names in the functions. I'm not entirely clear how the username and password to be authenticated are passed through to the check credentials function, but you've obviously based your attempt on the example from the shinymanager package, so I've just fixed that a little.