1

Due to shinyapps.io using session cookies (as documented here) and browsers retaining those cookies for longer than they should (as documented here), logging out of an app using https://accountName.shinyapps.io/appName/__logout__ (swapping out "accountName" and "appName" as appropriate) hasn't enforced re-authentication in quite a while, with no apparent fix on the horizon. One has to log out of both the app with the prior URL and their account with https://login.shinyapps.io/logout to enforce re-authentication.

Ain't no one got time for that.

I'd like to wrap both logout URLs in an action button for a seamless, fail-safe solution. The closest I've gotten so far is this (which must be tested on at least a Standard-level shinyapps.io account as a private app):

library(shiny)

ui <- fluidPage(

    titlePanel("Logout Test"),
    
    actionButton(
      inputId="logout",
      label="Log out",
      # swap out 'accountName' and 'appName'
      onclick="location.href='https://accountName.shinyapps.io/appName/__logout__';",
      onclick="window.open('https://login.shinyapps.io/logout', '_blank');" # problematic
    )
)

server <- function(input, output) {

}

shinyApp(ui = ui, server = server)

The crux there is window.open, which won't work on browsers that block pop-ups, and opens a second tab on browsers that do allow it, which is clunky (though it does log out of everything as intended). Requiring app end-users to modify their browser settings to enable pop-ups or alter cookie handling is even more clunky/dangerous.

When I try just using onclick="location.href='https://login.shinyapps.io/logout';" or onclick="window.location.replace('https://login.shinyapps.io/logout');" for the second URL, it skips over the first URL and logs out of the account without logging out of the app. Vice versa if I switch the order, neither of which force re-authentication.

I've also tried including the following on the server side, which while they do remove the cookies, doesn't work because browsers are squirreling them away somewhere as mentioned above:

library(cookies)

server <- function(input, output) {
   observeEvent(input$logout, {
       remove_cookie("therealshinyapps")
       remove_cookie("shinyapps_auth")
     })
}

  

I need something that either goes to those URLs sequentially in the same tab to run through both logouts or somehow does one of them in the background. I have the sneaking suspicion that these may be impossible due to malicious code defenses, but I may well have missed a trick somewhere.

4
  • Have you tried preventing the default behaviour of onClick? Commented Oct 25 at 17:51
  • @I_O I plugged in return false; at various locations in the onclick strings and it prevented navigation to any URL called after it. When placed at the start of the first string, nothing happens when clicking the actionButton. When placed at the end of the first onclick string or the beginning of the second, it goes to the first URL. When placed at the end of the second string, it goes to the second URL as it does normally. Plugging in event.preventDefault() did nothing regardless of where I put it - the actionButton always navigated to the second URL. None of these logged out of both. Commented Oct 27 at 18:45
  • Two consecutive location.replace or location.href calls won't work because as soon as the browser loads the new page your JS code is no longer executed (Please see this or this). I haven't tested it but maybe you can perform http requests via {httr2} instead. Commented Oct 28 at 9:19
  • @ismirsehregal yeah, I thought that may be the case. I hadn't considered httr2 - I'll see what I can do with that. Commented Oct 28 at 14:20

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.