Comments (14)
Hmm. I actually thought about attaching an observeEvent
to the logout button, but I was afraid of breaking something else.
I really should start learning about modules.
So I think this is a suitable solution to the problem, should I close?
from shinyauthr.
Have you tried wrapping the userBase
in a reactive that depends on the login status? Then it will fetch a new set of passwords when needed.
from shinyauthr.
Good idea. I'll try that as soon as it is practical.
from shinyauthr.
Alright I've tried something. I wrapped userBase
in a reactiveVal
and it didn't work. Here's what I did:
shinyServer(function(input, output, session) {
userBase <- reactivedbReadTable(con, 'userBase') %>% data.table() %>% reactiveVal()
credentials <- callModule(shinyauthr::login, "login",
data = userBase(),
user_col = userName,
pwd_col = userPasswordHash,
sessionid_col = sessionID,
cookie_getter = getSessionID,
cookie_setter = saveSessionID,
sodium_hashed = TRUE,
log_out = reactive(logout_init()))
# other code
})
and here's what Shiny says:
Listening on http://127.0.0.1:4219
Warning: Error in : Operation not allowed without an active reactive context.
* You tried to do something that can only be done from inside a reactive consumer.
65: <Anonymous>
Error : Operation not allowed without an active reactive context.
* You tried to do something that can only be done from inside a reactive consumer.
Warning: Error in logout_init: could not find function "logout_init"
1: shiny::runApp
My guess, the login
module is trying to get and set sessionID
in a non-reactive way. Or maybe I messed up somewhere else?
from shinyauthr.
I'm sorry, but the approach I suggested won't work. The data=user_base
object is not reactive. In order to make it reactive, the login module logic would have to be re-written.
You could add your own actionButton that triggers a session$reload().
You could try to make an observer get triggered by the change in credentials()$user_auth, but you'd have to use a reactiveVal to also make sure the user has already logged in at least once. Otherwise the app will immediately reload upon first load and get stuck in an infinite loop.
from shinyauthr.
I think we could probably handle this in the module logic but I'd need to look into the possibility of dealing wiith module arguments that could be reactive or static. @michael-dewar do you have experience with this? I'm thinking we could use shiny::is.reactive
to test the object that is passed for reactivity and handle it differently depending on the result.
from shinyauthr.
I did a quick test and shiny::is.reactive
seems plausible. But everything that is derived from the data
object would need similar treatment. Having two cases for everything would be complicated. Maybe at the start use:
if(!is.reactive(data)) data <- reactive(data)
and then convert all of the module logic to assume data
is reactive.
from shinyauthr.
While investigating other issues, I am now convinced that a session reload upon logout is very important. Maybe add an onLogout
argument to the logout module?
In a multi-user environment, some reactive values and calculations would stay in the session even if one user logs out and another logs in. Admittedly it was the result of my poor programming, but a simple page refresh would fix it.
from shinyauthr.
Agree a session reload makes sense on logout but I think this should be done from the main server function as I'm not sure we can trigger a full session reload from inside a module?
As @michael-dewar said you'd need to make sure it is not triggered on app launch when credentials()$user_auth == FALSE
by default, only after the user has logged in successfully then logged out again. You could use ignoreInit = TRUE
with observeEvent
to do this:
observeEvent(credentials()$user_auth, ignoreInit = TRUE, {
if (isFALSE(credentials()$user_auth)) {
session$reload()
}
})
from shinyauthr.
When I tried this I still got an infinite loop of reloads when I started the app. But that may have been due to something else in my app. However, this worked:
logged_in_at_least_once <- reactiveVal(value = FALSE)
observeEvent(credentials()$user_auth, ignoreInit = TRUE, {
if(isTRUE(credentials()$user_auth)){
logged_in_at_least_once(TRUE)
} else if(isFALSE(credentials()$user_auth) && isTRUE(logged_in_at_least_once())){
session$reload()
}
})
Unfortunately the login UI flashes because it appears after the logout and then disappears at the start of the reload.
from shinyauthr.
Okay, this is really hacky, but if you add removeUI(paste0("#",NS("login", "panel")))
inside the observeEvent in my previous post, then the login panel gets removed entirely and so it won't flash on reload. Here "login" is the id
you use when you call the login module, and "panel" is the internal id
for the login panel UI.
from shinyauthr.
Just tried your solution. A little bit hacky, but it works.
from shinyauthr.
I think in this case if you actually trigger the session reload by the logout button itself it will initiate the reload before the logout process is triggered inside the login module. This will avoid the problem of ensuring a successful login has already taken place and you won't have to hide the login panel etc.
Add this at the top of your server function:
observeEvent(logout_init(), {
session$reload()
})
from shinyauthr.
I just made a pull request in which I added an option to force reload the app on logout. What do you think?
from shinyauthr.
Related Issues (20)
- Additional info in the login box HOT 2
- Background and text colour HOT 1
- Issue adding a loading icon/spinner HOT 1
- live example app down? HOT 3
- CRAN submission HOT 3
- How to enable password coding by setting "sodium_hashed" parameter? HOT 2
- Error object 'js' not found HOT 8
- Error in shiny::isTruthy: attempt to apply non-function HOT 2
- Option to bypass/deactivate the login
- Error: shinyjs: Error parsing the JavaScript code provided. HOT 1
- shinydashboard shows app without login using shinyauthr HOT 1
- White font color on login button is difficult to see HOT 3
- login error after shiny timeout HOT 4
- Beautify the login window suggestion HOT 3
- Where should I put the data for my own app in shinyboard? HOT 1
- Cases for help HOT 2
- Using shinyauthr with shiny rmarkdown documents HOT 1
- Log password failures HOT 1
- Possible to call a database rather than download entire user base? HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from shinyauthr.