S
SolidJS•6mo ago
David C.

Is this a good method to secure routes?

<Route path="" component={RequireAuthContextProvider}>
<Route path="" component={RequireAdminContextProvider}>
<Route path="" component={SystemContextProvider}>
<Route path="/system">
<Route path="/" component={() => <Navigate href={'/system/information'}/>}/>
<Route path="/information" component={SystemInformation}/>
<Route path="/users" component={SystemUsers}/>
<Route path="/services" component={SystemServices}/>
</Route>
</Route>
</Route>
</Route>
<Route path="" component={RequireAuthContextProvider}>
<Route path="" component={RequireAdminContextProvider}>
<Route path="" component={SystemContextProvider}>
<Route path="/system">
<Route path="/" component={() => <Navigate href={'/system/information'}/>}/>
<Route path="/information" component={SystemInformation}/>
<Route path="/users" component={SystemUsers}/>
<Route path="/services" component={SystemServices}/>
</Route>
</Route>
</Route>
</Route>
export function RequireAuthContextProvider() {

const ctxMain = useContext(ContextMain)

onMount(() => {
if (!ctxMain.loggedIn()) {
if (ctxMain.userId()) {
ctxMain.setUserId(null)
}
if (ctxMain.userType()) {
ctxMain.setUserType(null)
}
ctxMain.navigator('/login')
}
})

return (
<ContextRequireAuth.Provider value={{}}>
<Outlet/>
</ContextRequireAuth.Provider>
)
}
export function RequireAuthContextProvider() {

const ctxMain = useContext(ContextMain)

onMount(() => {
if (!ctxMain.loggedIn()) {
if (ctxMain.userId()) {
ctxMain.setUserId(null)
}
if (ctxMain.userType()) {
ctxMain.setUserType(null)
}
ctxMain.navigator('/login')
}
})

return (
<ContextRequireAuth.Provider value={{}}>
<Outlet/>
</ContextRequireAuth.Provider>
)
}
export function RequireAdminContextProvider() {

const ctxMain = useContext(ContextMain)

onMount(() => {
if (ctxMain.userType() !== 'admin') {
ctxMain.navigator('/')
ctxMain.showErrorToast('You must be an admin to access this page')
}
})

return (
<ContextRequireAdmin.Provider value={{}}>
<Outlet/>
</ContextRequireAdmin.Provider>
)
}
export function RequireAdminContextProvider() {

const ctxMain = useContext(ContextMain)

onMount(() => {
if (ctxMain.userType() !== 'admin') {
ctxMain.navigator('/')
ctxMain.showErrorToast('You must be an admin to access this page')
}
})

return (
<ContextRequireAdmin.Provider value={{}}>
<Outlet/>
</ContextRequireAdmin.Provider>
)
}
24 Replies
Brendonovich
Brendonovich•6mo ago
This should handle navigating away if the user isn't authenicated just fine, assuming your auth logic is correct. I assume you don't want to hide everything until auth is complete?
David C.
David C.OP•6mo ago
I have a main context wrapping the entire thing, that has a fancy spinny mcbob
Brendonovich
Brendonovich•6mo ago
Ah ic I think you can remove the path="" for the layouts
David C.
David C.OP•6mo ago
loggedIn() ?
<div className={'main-container'}>
<ToastBar/>
<MainMenu/>
<Outlet/>
</div>
: <>
<ToastBar/>
<Outlet/>
</>
: <AuthLoading/>
loggedIn() ?
<div className={'main-container'}>
<ToastBar/>
<MainMenu/>
<Outlet/>
</div>
: <>
<ToastBar/>
<Outlet/>
</>
: <AuthLoading/>
Brendonovich
Brendonovich•6mo ago
And the SystemContextProvider could be put on the /system route
David C.
David C.OP•6mo ago
Oh, really?
Brendonovich
Brendonovich•6mo ago
Yeah path should be optional
David C.
David C.OP•6mo ago
So build a new context to be specific?
Brendonovich
Brendonovich•6mo ago
Nah just like <Route path="/system" component={SystemContextProvider}> System context on the system route
David C.
David C.OP•6mo ago
Aaaa aaa OK I see it that saves a nest
Brendonovich
Brendonovich•6mo ago
Not sure if it's important to you but this setup won't prevent the admin-only javascript from being publically accessible
David C.
David C.OP•6mo ago
Yeah that is also on my list
Brendonovich
Brendonovich•6mo ago
Ah That's the hard part haha
David C.
David C.OP•6mo ago
I'm not sure how that is done
Brendonovich
Brendonovich•6mo ago
Yeah afaik there's not really a good solution for it and imo it's not necessary
David C.
David C.OP•6mo ago
I have the backend checking session creds with every request action Its like a little experimental micro RPC thing I've got going on here 😆
Brendonovich
Brendonovich•6mo ago
Is part of your project's security requirements that even admin-only UI code can't be accessed publically?
David C.
David C.OP•6mo ago
It's a side project honestly, to learn production solidjs. So it would be nice to know of methods My thinking is I could bake in a session cookie value check into the onMount of the RequireAdminContextProvider I'm leaning heavily into the backend receiving credentials over fetch and verifying them...
Brendonovich
Brendonovich•6mo ago
I'm not aware of methods to do so but the common practice is to just host all client JS - including admin UI - publically, and then make sure that your backend is properly authorised, as it sounds like you're already doing
David C.
David C.OP•6mo ago
Yeah, I have it going to an async Python web framework that checks the auth on request using vite to compile
Brendonovich
Brendonovich•6mo ago
Requiring authorization to load specific chunks of JS is way harder and would need bundler integration or foregoing the bundler for sensitive files entirely so that you can serve them separately
David C.
David C.OP•6mo ago
I guess I could split the admin routes from the user routes Yeah that's where my thoughts went there https://github.com/CheeseCake87/vite-transporter
Brendonovich
Brendonovich•6mo ago
Also solid router basically requires that you load the entire route config upfront, so if you wanted to hide the admin route schema you might have a bad time
David C.
David C.OP•6mo ago
I put that together with the purpose of sectioning off the js Which uses the template engine in Flask/Quart to load entire vite apps .. but sectioning areas was the thought behind that
Want results from more Discord servers?
Add your server