I have written a shiny app behind a application load balancer on AWS, the authorization of the users happens via Cognito, the JWT from the header (x-amzn-oidc-data) is retrieved than passed into the function calls for doing GET request to the database in the backend (displaying the data), the problem that I have is that the JWT is only valid for ~ 2 minutes, once the JWT expires, the whole app crashes and becomes unresponsive (even the UI elements) and the only remedy is to do a session reload via the browser.
Is there some way to implement a token refresh in the background? Such that the token somehow refreshes right before the expiry time?
library(shiny)
library(jsonlite)
library(base64enc)
library(lubridate)
ui <- tagList(
tags$h2("AWS Token")
)
server <- function(input, output, session) {
observeEvent(session$request,{
if(exists("HTTP_X_AMZN_OIDC_ACCESSTOKEN", envir=session$request)) {
mytoken <- list("x-amzn-oidc-data" = get("HTTP_X_AMZN_OIDC_DATA", envir=session$request))
} else {
mytoken <- NULL
}
session$userData$mytoken<-mytoken
})
output$token <- renderUI({
mytok <- paste(session$userData$mytoken[[1]])
decode_jwt <- function(token) {
parts <- unlist(strsplit(token, "\\."))
if (length(parts) != 3) {
stop("Invalid JWT")
}
payload <- rawToChar(base64decode(parts[2]))
fromJSON(payload)
}
decoded_token <- decode_jwt(mytok)
exp_timestamp <- decoded_token$exp
exp_datetime <- as_datetime(exp_timestamp, tz = "UTC")
tags$div(paste("Token expires at:", exp_datetime))
})
}
shinyApp(ui=ui, server=server)
The expiry time can be easily decoded from the token, above is the set up of my app with a MWE (in this example nothing would crash, as the JWT is not used further for any GET requests). I have also tried playing around with invalidateLater
, unfortunately that did not help. The ideal scenario would be that the headers would refresh in the background "quietly" and that mytoken would reactively update, is this even possible with Shiny?