In going through optimizing my bundle and the initial page load, I made sure nothing is loaded that shouldn’t be (layouts, pages, components etc.). I don’t want to expose any information about my app without the user being authenticated.
I noticed two things.
These files are exposed and present on the initial login page load and therefore all the API information they carry.
Next, even though I use PrivateSet, the whole Routes.tsx file reveals all possible routes, even private ones.
It looks like you’re running on dev, and inspecting the dev output. This is probably expected behaviour.
On production, there’s a few things that happen:
graphql introspection gets disabled
react runs in production mode
vite will generate an optimised bundle
That being said, there’s always ways to find out what routes are available, etc. in an app. You should make sure that all your pages/requests require auth if you want them protected!
I’m still learning about bundling and vite, so this is definitely a journey for me but I think I’m beginning to understand. Yes, I was running in dev you’re right. My understanding was that whatever I could peak in dev will probably be open in prod as well. I solved this in dev at least by lazy importing anything that shouldn’t be visible unless you’re logged in. So if I have a DashboardPage, instead of adding code in that file I make a permission check and if it passes then the lazy loaded component gets rendered. This trick seems to prevent resources being loaded when a page is rendered and you can’t inspect the sensitive data in the lazy loaded component.
I guess what I’m trying to figure out is: once your browser downloads the bundle anyone can open their debugger and inspect it. For my use case, I can’t protect all the routes since login and forgot/reset pw need to be available. Well, I can see the LoginPage-<>.js when I hit my website, but I also see that “index-<>.js” file in the bundle that is my app.
It’s a large file and contains many things, one of which is:
Then, let’s say I have a search components that’s behind authenticated and authorized pages. Again in the index-<>.js file I can find information all about my business logic (the whole trusted doc store):
This is the case for every single code that’s behind a protected route/component. I understand that the browser needs the code to run my app correctly, is this just something we have to live with as react developers or am I missing something?
In my mind, the index-<>.js file shouldn’t contain anything that is behind authenticated calls or graphql fragment/trusted store information. My lazy import trick seems to work in prod too, where before I’d see the authenticated layout I use and now you don’t. You only see the first layout context that checks if you have permission, before lazy loading the necessary layout. I’m fine with that lazy loading trick, but my concern is about the trusted documents store being exposed without the user being authenticated.
is this just something we have to live with as react developers
Yeah that’s right - different way of thinking! Lets say nothing shows up (by breaking into chunks like you were doing) - what does this really achive? It just hides the route from the inspector, but it doesn’t actually stop someone from going to a page /profile.
In my mind, the index-<>.js file shouldn’t contain anything that is behind authenticated calls
Yeah reasonable to think this way, but SPAs tend to load things up front - but importantly unless you’re hardcoding things or loading data in different ways, the markup is harmless. It’s just styling and UI, but doesn’t actually contain any private data.
Instead its better to think of things this way:
all private data is accessed via GraphQL APIs. As long as you have @requireAuth correctly set on all the endpoints that only logged in users can access, no data is leaked. Because even if you go to a private page, or directly hit the graphql endpoint, no data is going to come back, just an error. Remember data is loaded by the browser after you go to the page, it isn’t part of the bundle.
the private pages in the router are for routing and UX. So if you try to go to a private page, and you’re not logged in, you’re redirected. Going there would only result in errors anyway, then the user would want to log in. It’s just a shortcut!
Remember data is loaded by the browser after you go to the page, it isn’t part of the bundle.
That makes sense, thank you danny!
I do client side role/permission checking as well as on the backend. I guess I just got paranoid in regards to the styling and layout being exposed, since that would give people information on what’s available in my app. Not the data layer of course, but just how my app works… I’m thinking ahead to competitors