We are using ShinyProxy with docker to host our shiny apps. For authentication, we use LDAP. Our setup works so far but now we need to meet a new security requirement: The user should be logged out after being inactive for 30 minutes.
I have seen the following configuration options:
server.servlet.session.timeout
and
proxy.heartbeat-timeout
but as far as I understand, this only stops the app container on certain conditions. Our requirement is to perform a logout so that the user needs to sign in again before being able to access their apps. With the above configuration, the app restarts when refreshing the page.
My approach so far has been to stop the shiny app from within the shiny-code when the user has been inactive (tracking with js). The app is then greyed out.
So what I am looking for is a configuration to automatically log out the user when the app stops.
(Or a completely different approach to the problem ^^)
Sometimes I do see a screen saying “You have been (automatically) log out - return to log-in” or something along these lines but I do not yet understand this behaviour.
So, I found a solution. I am redirecting the user to the logout-page.
JS_user_inactivity <- "
var inactivityTimeout;
var inactivityLimit = 30 * 60 * 1000; // Set inactivity limit to 30 minutes in ms
function stopApp() {
// Trigger an event in Shiny to stop the app
Shiny.setInputValue('stopApp', true);
}
// Function to reset the inactivity timer
function resetInactivityTimer() {
clearTimeout(inactivityTimeout);
inactivityTimeout = setTimeout(stopApp, inactivityLimit); // Set timeout for inactivity limit
}
// Listen for any activity (mousemove, keypress, etc.) to reset the inactivity timer
function registerActivity() {
document.onmousemove = resetInactivityTimer;
document.onkeypress = resetInactivityTimer;
resetInactivityTimer(); // Initialize the timer
}
registerActivity()
"
and then in server.R we do:
shiny::observe({
shinyjs::runjs(JS_user_inactivity)
})
observeEvent(input$stopApp, {
shinyjs::runjs('window.location.href = "/logout";')
})
1 Like
Hi, as you may noticed the heartbeat-timeout
setting does not actively check whether the user is actively using the app. It only checks whether the user has the app opened in their browser. The reason is that for ShinyProxy it’s very difficult to do this in a generic way that works for all apps.
So the best way is to implement this in the app, the solution with redirecting to /logout
is fine.