Check out a free preview of the full Intermediate Next.js course
The "Route Protection" Lesson is part of the full, Intermediate Next.js course featured in this preview video. Here's what you'd learn in this lesson:
Scott explains how middleware can be used to add route protection to the application. Middleware functions run on the edge, executing before the server processes cached content or matches routes. This allows the user to be redirected to the sign-in page if they aren't authenticated. Several other examples of middleware are shared, including conditional routing, managing cookies and headers, and CORS.
Transcript from the "Route Protection" Lesson
[00:00:00]
>> Scott Moss: We're gonna talk about protecting our routes with middleware. So right now, we protect our routes only if the route causes Git current user. So if Git currentuser is called inside of a page, then yeah, that'll redirect us to sign in, right? So if I go to, let's try to go, I guess any one of these, cuz they're like, they're parallel routes.
[00:00:23]
So let's just go to the users and the utils, and then I will just say, if true, all right, so this will always go to signin. So now, if I go back to our project, I'm already there, so it doesn't really matter where I go, it's always going to redirect me back here, right?
[00:00:49]
But you saw what just happened, right? The fact that it had to load the page up, and then it sent me here. That's gross, who wants to see that? I don't wanna see that. You don't wanna like, you try to get in here psych, like, you don't want them to see anything.
[00:01:05]
Because if they're not signed in, none of that data's gonna load anyway, cuz it's all segmented off of a user ID. So, what's the point of even going there? We can prevent that from even transitioning in the first place by adding middleware. So we're gonna add middleware to protect our app from users who aren't signed in versus waiting for the page to attempt to load the user and then if not, redirect them back to Sign in.
[00:01:30]
How about we just don't even let you go to that page at all? So let's do that. Best way is to make a file on the root, well, the only way is to make a file on the root called middleware.
>> Scott Moss: And it's not really difficult at all, I have a little slide on it that kinda goes through some use cases.
[00:01:54]
But the only thing you really know about middleware, it's a function that runs on the Edge, so it runs before your routes are accessed, it's an Edge runtime. So it's not node runtime, so you can't do node things. So you can't connect to a database that isn't serverless, you can't connect to a database that isn't HTTPS and make calls that way, you can't do anything you can't do in the Edge, right?
[00:02:25]
It's an Edge environment, which is very limited, but still JavaScript, obviously. So some of the use cases are authentication and authorization, that's what we're gonna do. This is why I stored the JSON Web Token in a cookie, because you can access cookies on the Edge, because you can access headers on the Edge.
[00:02:42]
Server, server, redirects, we'll be doing that too, this allows you to dynamically redirect or even rewrite, which is a big difference. Redirect and rewrite are two different things on the Edge. Bot detection, so you can detect IP addresses that are coming in at some interval, use some HTTP-based Redis instance to keep track of how many times this IP address is hitting you over a certain time.
[00:03:06]
And then you can block them. So that's a rate limit and things like that. Logging analytics, that's great. You can literally just, if you have some HTTP-based analytics that you want to send information to, so whatever someone comes in, you can look at the request they're asking for and send that up.
[00:03:24]
Feature flagging is also a really good, in combination with some type of Edge-based storage. Again, like ACP base or Redis, or whatever like that. You can store user's ID with some objects on what features they're allowed to use, and then you can change that on the fly without having to redeploy your app.
[00:03:43]
So that's feature flagging. So you can do a lot of stuff with that, it's pretty cool. Yeah, just basically don't do heavy stuff there, it's on the Edge. So don't try to solve in Queens inside of a middleware function, don't do stuff like that. Don't try to make complicated fetching calls, I mean, you can, but you probably don't want to.
[00:04:11]
The whole point of the Edge is it's supposed to be fast. You kind of defeat the purpose if you're like, I'm gonna make ten calls to the Reddit API right here on the Edge, and then get the data back. Okay, I don't know why, a lot of the Edge computes also have limits on how long those functions can run anyway.
[00:04:26]
So you'll hit them long before you even see results. Anyway, pretty simple, you make a middleware file, you export a function called middleware. It takes in a request, and you can do whatever hell you want. The other thing is this config option right here. So this config is the matcher.
[00:04:42]
There's a lot of different ways you can make a matcher. You can pass a string like this that uses this glob syntax. You can pass an array that matches like this, we'll probably use something like that. You can get pretty advanced with this. As far as like rewriting, so you can check if URL comes in, you wanna rewrite it to another URL.
[00:05:05]
This is how you might handle things like cookies, so you can set cookies, is how you might handle something like CORS, if you wanna allow that. So, there's really a lot going on here, yes. Which one of these methods will be good for implementing route-based protection based on user role?
[00:05:25]
Route-based protection based on user role. Well, first, it comes down to, where are you storing the user role? So, are you storing the user role in a cookie that you can access? Are you storing the user role in a HTTP-based storage that you can access? So, first you got to figure out where that is stored, 2, how do you associate the incoming request with that user role, if it's not stored on the cookie?
[00:05:53]
So once you solve that, and there's many ways to solve that, then, how do you control access? Well, you would only wanna control access here, I guess, if there were different segments of your app that were completely segmented off depending on role, like by route. Like for instance, if there was a slash admin for your app and you only wanna show that if the user is at the admin role, yeah, that would make sense.
[00:06:21]
But if you had an app where it wasn't segmented clearly by a route, like, you might have one route, but within that route anybody can see the page but only an admin can see this one thing. And this wouldn't be that useful, cuz this is route level. So you probably wanna do that in the app.
[00:06:37]
So if it's route level, yeah, figure out where you wanna store the role, figure out how you associate the request with the role if it's not a cookie, and then you do your redirects. I saw this user who came in from this request, does not have the role of admin, but they're requesting slash admin redirect them or block them or whatever you wanna, go delete their account from strike.
[00:06:59]
Whatever you wanna do, you can do whatever you want, but I would say it probably needs to fall within those realms because the middleware doesn't know about the components on your page. It only knows about routes. So yeah, the actual methods, we're gonna use some of them right now.
[00:07:12]
Rewrite, redirect, cookies get, cookies set, yeah.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops