auth0
auth0 copied to clipboard
Shiny app goes gray after refresh
I set up auth0 authentication, everything works fine on login and log out, but when I click refresh in my browser (Firefox), shiny up goes to gray and it returns an error (from shinyapps.io logs):
2019-10-16T13:08:13.633470+00:00 shinyapps[1335290]: Error in httr::oauth2.0_access_token(api, app(redirect_uri), params$code) : 2019-10-16T13:08:13.628803+00:00 shinyapps[1335290]: Warning: Error in httr::oauth2.0_access_token: Forbidden (HTTP 403). Failed to get an access token. 2019-10-16T13:08:13.633472+00:00 shinyapps[1335290]: Forbidden (HTTP 403). Failed to get an access token.
This is a problem and sadly there's no workaround for now. You need to manually delete the "code=xxx" parameter if you want to refresh your app
Maybe it is possible to programmatically delete code part when refreshing the page event occur, using JavaScript?
Yeah, you can probably use some client side JS to check if the page has been reloaded. For example: https://stackoverflow.com/questions/5004978/check-if-page-gets-reloaded-or-refreshed-in-javascript
Thanks, I will try to implement this JS code.
For a temporary workaround I used the history.pushState
method to update the browser history once the page has loaded. An ugly hack but seems to do the trick.
Hi @gbradley can you give me a working example where I can use the same method for my shiny apps. Thanks.
@mohan1331 Here's what I added:
tags$script(JS("setTimeout(function(){history.pushState({}, 'Page Title', '/');},2000);")),
This simply waits for 2 seconds after the page loads before adding "/" to the browser history stack, meaning the URL parameters are removed without reloading the page.
@gbradley Where in your Shiny app did you put this code? TIA.
@snestler This is how I included it in my apps. What @gbradley gave is a Javascript code so we can put it inside tags$head. I like to call my tags at first. So
ui <- tagList( tags$head( tags$script(JS("setTimeout(function(){history.pushState({}, 'Page Title', '/application_name');},2000);")) )
This can be followed by your usual UI code.
You can replace your application name in the code so that refreshing the page will refresh the app without any error.
Thanks, @gbradley this is the first thing I do whenever I create a shiny application with auth0.
@mohang13 I'm still having issues getting this to work. Part of it is my lack of JS knowledge. I'm wondering if it has to do with not having the correct entries for 'Page Title' and '/application_name'. I'm pretty sure I've got the second one right, but am not sure what to put for the first one. Can you provide a specific example for me to reference? Thank you.
@snestler I'm attaching a sample shiny application named 'github_app'. As you can see I mentioned the same name in tags$script. Only change the app name (here it is github_app) in your code do not change Page Title (it'll automatically take your page name).
library(shiny)
library(htmlwidgets)
# Define UI for application that draws a histogram
ui <- tagList(
tags$head(
tags$script(JS("setTimeout(function(){history.pushState({}, 'Page Title', '/github_app');},2000);"))),
fluidPage(
# Application title
titlePanel("Old Faithful Geyser Data"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
output$distPlot <- renderPlot({
# generate bins based on input$bins from ui.R
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins + 1)
# draw the histogram with the specified number of bins
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
}
# Run the application
shinyApp(ui = ui, server = server)
I forgot about calling the library htmlwidgets in my previous answer, usually my other libraries like DT calls it automatically. If you still have trouble let me know.
Thank you. This is helpful; I wasn't including the whole fluidPage inside the tagList. And the library(htmlwidgets) call was part of the issue. I've got it "working" now, in that clicking "Reload" will restart the app, rather than disconnecting from the server.
But, I seem to experience random disconnects when working in the Shiny app when this is enabled. Not sure why that might be. Any insights?
@snestler What do you mean by random disconnects? Do you see an error in auth0.com logs? Anything printed in your Rstudio session? It would help if you included your code and deployment details like OS, R version etc.
Also, I had to use: tags$script(htmlwidgets::JS("setTimeout(function(){history.pushState({}, 'Page Title', window.location.pathname);},2000);"))
. This worked in both development (where pathname = '/') and in production where it is not root.
Any workarounds for this issue ? (Besides what @gbradley suggested)
This is a pretty important issue to address. Why is it marked wontfix?
The problem of this solution, is that if the user don't logout, the page will be logged forever.
I used replaceState
instead, so it doesn't add a new entry to the history but replaces the one that has the 'code' parameter.
tags$script(JS(
"setTimeout(function(){history.replaceState(null, '', '/')}, 2000);"
))
I will just point out that this hack works,
setTimeout(function(){history.replaceState(null, '', '/myAppName')}, 2000);
but I did encounter a problem where it prevented all my page resources (images, some CSS and JS) from loading when I moved my app to my own Shiny Server instead of shinyapps.io. This flummoxed me for a couple days. I presume the solution to that would be to extend the wait time from 2 seconds to 5, 10 or 20 seconds. Overall I would say that changing the state like this works but causes unexpected behavior and it would be cool if auth0 can figure something out for this. Cheers!