accessing JavaScript localStorage in R Shiny

I am pretty new to Shiny -- if there is a better way to do this, I'd appreciate being pointed in the right direction.

That said, what I would like to do is connect a shiny app to a django rest framework API. First off is authenticating the user and hopefully saving the authentication token on the client side with JavaScript.

I am trying to follow the instructions here:

Shiny: Communicating with JavaScript

My idea is that I would store the user's token in the javascript localStorage.

In the app ui, I have this:

ui <- shiny::navbarPage(
  "Yeast Calling Cards DB",
  shiny::tabPanel("DB Tables",
                  shiny::selectInput(
                    "db_tables",
                    "Choose a table",
                    choices = names(raw_db_tables)),
                  table_detail_ui('db_table')),
  shiny::tabPanel("User Auth", login_ui("user_auth")),
  header = tags$head(
    tags$script(shiny::HTML('// In the client side JavaScript code
                $(document).on("shiny:connected", function() {
                console.log("hello world!!")
                    // Retrieve the authentication token from localStorage
                    var authToken = localStorage.getItem("authToken");
                    // If the authentication token is null, do nothing
                    if (authToken == null) {
                        return;
                    }
                    // Otherwise, set the authentication token in the Shiny input
                    Shiny.setInputValue("authToken", authToken);
                });
                // Custom message handler to save the authentication token in localStorage
                Shiny.addCustomMessageHandler("saveAuthToken", function(token) {
                    console.log(token);
                    localStorage.setItem("authToken", token);
                    console.log(localStorage.getItem("authToken"));
                });'))
  )
)

And in the login module, I have this:

#' Docstring omitted
#'
login_ui <- function(id) {
  shiny::fluidPage(
    shiny::textInput(shiny::NS(id, "username"), "Username"),
    shiny::passwordInput(shiny::NS(id,"password"), "Password"),
    shiny::actionButton(shiny::NS(id,"login"), "Log In"),
    htmltools::p(
      "The token  is: ", shiny::verbatimTextOutput(shiny::NS(id, "token"))
    )
  )
}

#' Docstring omitted
#'
login_server <- function(id) {

  shiny::moduleServer(id, function(input, output, session) {

    # Make a request to the REST API to authenticate the user
    shiny::observeEvent(input$login, {

      shiny::req(input$username, input$password)

      auth_response <- httr::POST(paste0(Sys.getenv('DB_HOST'),
                                         database_info$endpoints$auth_token),
                                  body = list(username = input$username,
                                              password = input$password),
                                  encode = "json",
                                  httr::accept_json())

      if(httr::status_code(auth_response) == 200){
        # Send the token to the client side JavaScript
        session$sendCustomMessage(
          "saveAuthToken",
          httr::content(auth_response)$token)
        print(input$authToken)
      } else{
        session$sendCustomMessage("saveAuthToken", 'unknown username or password')
      }
    })

    # Render the token
    output$token <- shiny::renderText({
      if (!is.null(input$authToken)) {
        input$authToken
      } else {
        "No token found"
      }
    })

  })
}

The result of the console.log lines is good -- the token is getting passed, and it is getting added to localStorage.

But, input$authToken never updates.

My question is: is this even possible? can I save the token for the duration of the session and access it from different parts of my shiny app, after the user is logged in? If so, how to I access it, once it is in localStorage?

The "full" app that I'm working on is here, for what it is worth:

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.