Introduction to the JAMStack Protecting Private Routes
Transcript from the "Protecting Private Routes" Lesson
>> So now if I click Log out, I can log out. And okay, we just found a problem. If I go back to my login page, what's exciting is the profile's gone. The last step that we need here is we need to actually protect these routes. So let's make that a thing.
[00:00:21] So the way that we're gonna do this is we're gonna use a pattern that I call a private route, where what we're effectively gonna do is load a component. That component is going to check if authentication is present, and if so, it will load another component. And if not, it'll bounce us to the login page.
[00:00:39] So it's a way for us to say, basically, this component needs to clear an authentication hurdle before it can be visible. To do that, I'm going to create a new component called private-route.js. And inside of that we're gonna import React from react. We will also import navigate from gatsby.
[00:01:02] And we're gonna get that useIdentityContext hook again. And that comes from react-netlify-identity. And then we're gonna define our PrivateRoute component. And this is gonna accept a component prop, which is the component we want to protect. But React has a thing where it wants component names to be capitalized, so I'm gonna rename it to Component, if I can spell it.
[00:01:39] And then on top of that, we're also gonna get the location. We wanna get the location out of there so that we can tell where we are. And anything else that comes in, we're just gonna store up into this rest. So inside I'm gonna grab the identity out like we've been doing with useIdentityContext.
[00:02:02] And then I'm going to figure out if we're logged in. And that's gonna be identity, and identity is logged in. And then down below here, I'm going to check if we're logged in. So if we're not logged in, And the location pathname does not equal dashboard/log in. Now, this theoretically shouldn't be possible to hit that because we're only gonna call this private route for the slash secret and the slash base.
[00:02:43] But I've gotten myself into infinite loops and I figured like I'm never gonna regret that check. So even if it seems impossible, whenever you say estates impossible, somebody will find out how to get into it is what I've learned. [LAUGH] so if we find out that someone's not logged in, there's my typo.
[00:03:04] Then, we're going to navigate to the dashboard. Login and we're gonna replace state again. And then just in case it tries to render something before that redirect finishes, we're gonna return null so that we don't show anything. We want nothing to show up on the screen. Now, if we get past this check then that means that we are logged in.
[00:03:28] So we are going to be able to just return the component whatever that was, and give it any props that were passed in. So in doing this the pattern that we've adopted here is that we're going to say, if we're not logged in, then always bounced to the login page.
[00:03:48] If we are logged in, do whatever you were gonna originally do, that's fine. So it's just a gate is really what we've done. So if we export this as our default, PrivateRoute, then we need to rewrite our dashboard routes to actually use this. So let's get the dashboard.
[00:04:11] And I'm going to import PrivateRoute from components/private-route. And the way that we're going to use this is to just replace this with PrivateRoute. And then we can add a component and that'll be the component that we wanna use. So we'll do the same thing here, PrivateRoute, and the component is the one that we wanna use.
[00:04:45] So in doing this, what we theoretically assuming all is gone well, have just done, is set this up so that if I try to manually navigate to a page that I don't have access to yet. So let's try to go to base. It redirects me out. So now we have an authenticated app.
[00:05:06] And what's nice about this is if we look at the code nothing that we're looking at in here is privileged. If somebody were to get access to the static files, and they looked at, say, the the route base, we're not gonna build static assets that have sensitive user data.
[00:05:30] We're gonna get that asynchronously. We would have the user context and we'd be using that identity object to say, hey, go load any data for the person with this email address or with this user ID. And then display that on the page. So what this means is that we're effectively saying even if someone hacks our CDN and gets access to all the files that we've shipped.
[00:05:53] They dan deface the site, they can make it do all sorts of things,. But they couldn't get user data, they wouldn't be able to get to the server itself or access the user's data. So this is kind of a nice pattern for making that work. And then, for the average use case for someone who's trying to log in here.
[00:06:13] Once we're logged in, We can see all of our stuff and it will let us login. And then if I try to go to that login page it'll just take me back to what would be the dashboard home. So that is an authenticated dashboard app.