In this series we’re exploring different patterns for using next-auth with Next.js for easy and powerful login and sign up for your app. In this next installment we’ll talk about requiring the user to be logged in to see parts of your app.
Other articles in this series:
In most apps, there are features and screens for which we want to require the users to be logged in. For our example app, we’ll assume the user needs some kind of personal dashboard they’ll see only when logged in (since, we can’t know whose data to put on the dashboard unless we know that (1) they’re logged in and (2) who they are),
First we’ll create a dashboard page for our app with some content in it. We’ll require that a user log in to see this page.
Looking good! Chakra-UI is pretty great.
The above works well if the user knows the address of the page, and is trying to see it without being logged in. This is an effective measure, since there’s no way they can get in.
But why show them a link to it in the first place? We should only show links to restricted pages when the user is logged in.
It’s just some styling, and has the ability to pass in children which is important since that makes it fairly composable. That is, we can pass it any children we want and it’ll still work, which also means we can wrap it easily with other components that pass specific children to it.
Now we’ll want a logged in and logged out version of it:
The logged in links to the dashboard we created, and also shows a Log out link (which we shouldn’t show when someone is logged in either).
Now how do we get them to show conditionally? Easy. We export another component that takes in the session as a prop. If it exists, we show the logged-in version of the Navbar. Otherwise we show the logged-out version.
Boom. Only logged in users will see the dashboard link, so there’s a second layer of protection on the private page.
So we’re redirecting anyone that views the dashboard in the browser who isn’t logged in. But the dashboard will inevitably need some data, which we’ll have to create an API route for. What if someone were to request that API route directly, without being logged in?
We don’t want people fiddling with that endpoint without having at least logged in first. So our API route will need to check that the user is logged in as well. In general the back-end is even more important to restrict, since that’s where all valuable data will come from. So for security reasons and other reasons, let’s put a redirect there as well.
Let’s add an API route to send us some data:
If we hit this endpoint in Postman, we’ll see the data sent back in JSON:
Then we can have the dashboard page use this data with a simple React fetch/setState pattern. The dashboard will look exactly the same, but it will now render the data dynamically.
Now you’ll see below that the postman request will return a 307 for temporary redirects.
NOTE: When testing in Postman, make sure you have automatic redirects turned off in the settings, or you’ll see a bunch of HTML as your response.
Great. Now we’ve locked down the dashboard from both the front-end and the back-end. Go celebrate with your beverage of choice 🎉
Mike Cavaliere is a Senior Engineering Strategist at Echobind. He’s been working with web and mobile software for two decades as an engineer, manager, and one-time CTO. He’s written dozens of articles, been on a number of podcasts, and authored a book entitled Cut into the Jamstack: Build and Deploy a Full-Stack Application Using React and Next.js. He’s a parent of two boys, loves travel, cocktails, comedy, and most music, with a special place in his heart for 1990’s hip-hop.