Production-Grade Next.js Protecting Pages in Server Side Props
Transcript from the "Protecting Pages in Server Side Props" Lesson
>> We left off last on, What did we do? We had yeah, auth with JWTs, so we had the sign in what the sign in page and the social auth with GitHub using the next auth plugin. So now what we need to do is we need to now they're able to create an account.
[00:00:17] And lock things down with the JWT, we actually need to implement that lockdown on some of the resources that we don't want people to get access to. So as of right now, the only resource we wanna block people from is the app page, so that's what we're gonna do.
[00:00:32] So in order to do that, we're going to start this new lesson over here protecting pages, which I'm already on. So we're gonna use the next auth client, which gives us a function called getSession, that basically just gets the current session of the user. And we can use that session to determine if someone is or isn't signed in and then we can pass that session.
[00:00:56] Because of that provider that we added, that session gets pretty much accessible everywhere in our application. So we can do all types of stuff, so that's what we're gonna do. We're gonna grab that session and then we're going to, depending on if you're signed in or not on that auth page.
[00:01:11] We're gonna basically redirect you, try to get you out of there, so you can't see this page, so let's do that. So I'm gonna head into my app, I'm gonna close this stuff, there we go. And then I'm going to go into pages, app, and then this to catch our route here.
[00:01:41] And then we're gonna go down here and we're going to create a server side function, so we haven't done it yet. So we're gonna say export async function, getServerSideProps. So why are we doing get server side props and not get static props and what's the difference, right? So we're not doing get static props here, because this part of our known application is actually a dynamic page.
[00:02:15] It's not a static page, we don't want to pre generate this page at build time, although we could, we're not. And that's just because how the behavior that we want for this you can think of this page is basically like a single page app. We want it to be always be be dynamic, it's always live.
[00:02:35] If we had to generate this ahead of time, I mean that can hit our database and do a lot of calls, so we're just not interested in that. So this is like the equivalent of trying to statically generate your Facebook home feed or your Twitter feed. It doesn't make sense to do that I mean, you could, you could pick the first ten tweets above the fold and statically generate that.
[00:02:55] And as soon as it connects and you scroll, you go get the rest, that's a big optimization, but we're not gonna do that. We're most likely just gonna make this dynamic, so there's two ways to make it dynamic. You make it a single page app, you don't have anything on the server, which we could also do here.
[00:03:09] Or we can just say, let's just fetch everything initially on the server, and then we'll handle like mutations on the client. So that's pretty much what we're gonna do. So to get server side props here, we're gonna get some contexts which is basically gonna have like the request and the response object on it.
[00:03:27] Because get server side props actually behaves very much like API route, very much like this where you have a request and a response. Except for it's blocking whatever page this is exported from that page won't render. Until this function has finished its execution and return some props. So you can do whatever you want here, whatever you can do inside of these functions you can do inside of this function, anything.
[00:03:54] So that's what we're gonna do, so the first thing we do is we're gonna get our session so we should have a get session from up here. So I'll do next auth slash clients, there should be a get a session here like that. And then what I'm going to do is I'm going to get a session, so I'll say session, Equals, await, and then get session and I think this just takes the context object like that.
[00:04:27] So I have a session here and that was gonna return it as a problem. Like that, so now we have a session, so that provider that we made here is now gonna get that session. It's gonna get added here cuz these are the page props, these page props get created when we return them here.
[00:04:46] And then it's going to get injected into the provider, so that means we can actually use them. And a hook up here just like we did in the sign in like if you look at the sign in. We use the hook here to get the session that hook is hooking into that provider to share the context of the session.
[00:05:02] All right, so get service I props injects it and then a hook allows us to get it on the client. Now, you might be thinking, well, how does it happen, it's on the server? Well, that's because RxJS preserving that data, the nitty gritty of how they pass data from server to client is at the end of the day.
[00:05:21] They associate pages with like different hashes and IDs, this page is this hash this ID. Here's the data that was requested for this page, when it loads up, save it in a JSON file somewhere. And then when we load this up on the browser, match the hash with this hash we have over here and passing that data to its props.
[00:05:39] That's basically what it's doing, if you go look at the output of all this, it's JSON files that they're saving stuff in and then they're passing it in. And that's how they pass the data from server to client, so that's all there. And then we're gonna use that same hook, so we're gonna do the useSession.
[00:05:58] Like that, and I'm gonna say const, I think it's like session and there's loading I think we can call wherever you want, right? It's all right, whatever and then we'll say use session, I could also just pass this session I mean, I am passing it as a prop.
[00:06:23] So I could also just refer to it here as a prop, and you can get access to it, either way is fine. The same session doesn't matter, but yeah, just to let you know, I could totally do that. So if you're wondering why, hey, why don't you just use that as a prop?
[00:06:35] Yeah, I could it's here, but I'm just gonna use this session thing here. So then what I'm gonna do is I'm gonna say if were loading to get the session, I don't want you to see anything. I literally don't want you to see anything on this page, so I'm just gonna return no, you're just not gonna see anything.
[00:06:55] If you return those I've react render it doesn't show anything, so that's what null does. So overloading, get out here, you not gonna see anything and then what I wanna do is right now this thing just says if false. So I don't wanna do that Instead I wanna say, if it's not loading and we still don't have a session, then you're not authorized.
[00:07:19] Cuz if we're downloading the session, and we still don't have a session back. You're not authorized, so I'm going to go ahead and open up this dialog which is a modal. And it's gonna say you're signed out, click here to sign in, and I'm just making sure that you can't close this modal.
[00:07:37] So you can't cancel it, you can't close it, you can't click on the overlay, you can't hit escape. It's literally unclosable modal, and because it's inside of the if statement I'm not even rendering the app. It's this modal, or it's this app like you literally won't see anything, so while you're waiting for the session to come back, you won't see anything.
[00:07:59] If the session comes back, and it's null you'll see a modal, if it comes back and it's not null you'll see this page. And then the last thing I wanna do is is pass in the user here, so I'll just say session dot user. Cuz we logged the session before, and we saw that there was a user object on it.
[00:08:14] So that's actually what I'm passing in here, session dot user, so now if we go try this, see what happens. So that should still be running, let's go back to our browser. Try to do all this stuff again, Okay, so you can see right here, one thing you might not have noticed is before I move on, so the whole null is actually using that session hook.
[00:08:42] And what it does with it, it will, depending on if you're logged in or not, it will put a button at the top right at the null bar that says sign in. If you're not logged in, if you are logged in it'll say go to dashboard, right. So it's doing that based off the session, so you can see I am logged in so it says go to dashboard, right?
[00:09:00] But if I sign out, I don't know why I clicked that I sign out of this by clearing these cookies, you can see it says sign out, it immediately changed. Right and that's because we're getting the session on the client side and it's getting that, it's being reactive.
[00:09:19] Also those hooks are very smart, hooks like that react query and use and SWR. What they do is they'll track when you focus and leave focus of your app. So for instance, if I click here, and then click back, let me see if you see the network tab here, watch this.
[00:09:37] So I'm in here, I'm gonna click over here you can see you want to go get the session. I'm gonna click back over here, and once you look at the session, I'm gonna click back over here, and once we get the session. So it's keeping track of if I'm focused on the window or not, to make a call to get the session.
[00:09:53] So you're always getting the latest information about if someone signed in or not. It's pretty cool little feature that's built into these hooks, so pretty nice. So yeah, it'll always go make a call, so if someone like I'm gonna leave, I'm gonna go to another tab. And when they come back here, it's gonna make a call to see if they are logged in.
[00:10:11] As soon as they come back, as soon as this window focuses again, pretty nice, okay, so we're gonna hit Sign Up, Sign in with a GitHub. Okay, I think it's because I'm not passing in any folders that's right. It's here, I got a pass on then to this thing, there's nothing here and that's why it's freaking out.
[00:10:37] We haven't got to this part yet okay, so I'll just do something like that. I think that will do it. There we go, okay, debugging that's crazy, okay, so to fix that bug, again, that bug is basically. One of the ever green component was freaking out because it's expecting it to have some children over menu item.
[00:11:07] No array was set so it was undefined so it was freaking out, so I just gave it some mock data to satisfy, so we can render. So you should see this, see this little mock folder that I have here, so now that's because we're signed in now, right.
[00:11:21] So if I try to go back to sign in, It's gonna redirect me back here cuz I'm signed in automatically I don't have to do anything. There's ways to get past that sudden flash of, God, I don't see that jarring flash. At the sign up page and then coming back here, but that's pretty much it.
[00:11:39] So now if I wanna sign out if we want to test that modal so I go to application, I'm gonna clear this will close this and boom. Soon as I close it session expired automatically, I didn't have to do anything. That's because it's tracking that session every time I focus and in and out of the window, so I made the call to get the session.
[00:11:58] They didn't see it in the cookies, so I can't do anything I try to click, can't go anywhere. There's no cancel button, can't hit escape, so you got to click here to go sign in and now we're back here, so I sign in again. And we're back, all right, also I thought that was pretty easy to do, I've done something like this before manually, and it's a lot more work than that.
[00:12:25] This was really easy, I mean even just setting up that focusing on the windows and analysis is not an easy task. So they did a really good job there, yeah, so that's how we're gonna lock down our pages. So if we had any of the pages in here that we want to lock down, I don't know.
[00:12:42] We were charging people to look at blog posts cuz our blog posts are that good. All right you do the same thing, [LAUGH] go do the same thing we just did on the blog post page. And lock it down, if you want to I mean, you got to survive out here.