Hey all, I really have an obscure bug that I reall...
# kobweb
c
Hey all, I really have an obscure bug that I really cannot wrap my head around... I have a portfolio website where a backoffice is coupled to it. This backoffice is only accessible by authenticated users, where the token is saved in the
localStorage
. Then, in my
AdminHomePage
I get the token from the localStorage, parse the token and check if it is expired or not. Should the token not exist, or be expired, the check then automatically navigates to the login/home page. If it does exist, it should stay on the page. However, the check somehow causes a flicker in the pages. Even though the check is still happening, the application already navigates to the Home/Login page, but then in a split second the check completes and shows the correct page (the admin panel)
Copy code
@Page
@Composable
fun HomePage() {
    isUserLoggedIn {
        HomeScreen()
    }
}

@Composable
fun HomeScreen() {
    AdminPageLayout {
        AddButton()
        HomeContent()
    }
}
The
isUserLoggedIn
function looks like this
Copy code
@Composable
fun isUserLoggedIn(content: @Composable () -> Unit) {
    val context = rememberPageContext()
    val tokens = remember { window.localStorage.getItem("tokens") }
    var tokensAreValid by remember { mutableStateOf(false) }

    LaunchedEffect(key1 = Unit) {
        tokensAreValid = if (!tokens.isNullOrEmpty()) TokenManager.areTokensStillValid(tokens) else false
        if (!tokensAreValid) {
            context.router.navigateTo(Navigation.Screen.Home.route)
        }
    }

    if (tokensAreValid) {
        content()
    } else {
        println("Loading...")
    }
}
This only happens in an exported project, as long as I'm running the actual debug/develop mode this is not happening. I'm afraid that it is not clear what I'm talking about, so if you need more information, don't hesitate to ask. As far as I know, the
localStorage
is the culprit, if I remove that line and just hardcode a check, all works as intended... anyone ever had this issue?
s
There's too much home .. HomePage, HomeScreen, AdminHomePage, Home. Is
Navigation.Screen.Home.route
the "login" page or is that the same as
@Page fun HomePage()
? Is "Loading..." being printed before redirecting? btw access tokens shouldn't really be stored in localstorage
l
What you're seeing is an artifact of how the export works. During the export, kobweb navigates to each page and saves a snapshot of the html. Then when you run the exported site, it shows the saved html immediately, and only once the JS loads does it run the actual code, rerendering the page in the process. To fix your issue, guard any code you don't want to run during the export with
if (! AppGlobals.isExporting)
, which in your case should probably be the token checking logic. This will make the redirect not happen during export, preventing the flash.
👍🏻 1
s
but why is there a flash? once routed to login, the check shouldn't be able to complete to true and render the admin content?
c
First time making a website so I'm still learning the best practices. What would be a better option to work with accessTokens on the frontend? The only thing I actually use them for is adding them in the Authorization header or use them to check if the user is logged in or not. Ooh wow! That really was the issue! I would've never found this on my own! Thanks @Letter As far as I know (and understood), the snapshot only contains the html of the Home because that what it found when running the export. But when the actual Page tries to load, it then checks what is in the current browser's localStorage and completes correctly, thus showing the correct page content.
s
httponly cookies are usually preferred. owasp cheatsheets are always worth a look. cookies can't be accessed by js and are therefor not vulnerable to cross site scripting
l
Yup, that's right @Christiano. Glad that fixed it!
c
Ooh great, recently read something about that, so I'll look into it in more depth then. thanks for the help guys/gals! 😄