DEV Community

Protecting static pages in Next.js application

Ivan V. on April 05, 2021

In this article, I will explain how to structure your Next.js application so you can protect your static pages from unauthenticated access. I will ...
Collapse
 
prajwalkulkarni profile image
Prajwal Kulkarni

Great writeup. However, I've tweaked your code a bit to fit my needs(using redux-state) instead of context, and I'm facing an issue. I'm using getStaticProps on a dynamic route which is a protected route, wrapped within AuthGuard. When I hit the protected url, I'm successfully redirected to the Signin page if I'm not authenticated, but when I inspect the network tab, I can see that the contents of the protected page are downloaded on the client (as JSON). Also, If I'm authenticated, I'm unable to reach the protected routes. Any suggestions on how do I go about this? Thanks.

Collapse
 
ivandotv profile image
Ivan V.

Since pages are static they are always downloaded, there is no way around this except to have server-rendered pages where you check if the user is authenticated server-side, and respond accordingly.
You should not have your static pages contain any hardcoded data that is security-sensitive, rather you should load all sensitive data when the user is authenticated (by sending fetch requests to load sensitive data)
A great example of this is the Vercel dashboard.

Collapse
 
prajwalkulkarni profile image
Prajwal Kulkarni

The static pages are used for a dynamic route, meaning there could be multiple entries that would reach this page, NextJS is forcing me to use SSG using getStaticProps and getStaticPaths , and hence not able to do much after the component mounts. Regarding the data in the page, it's the data that belongs to the user, so it's pretty sensitive. Given the scenario, is server-side authentication check the only workaround?

Thread Thread
 
ivandotv profile image
Ivan V.

How are you getting the data for the user? There is no request/response objects in getStaticPaths

Thread Thread
 
prajwalkulkarni profile image
Prajwal Kulkarni

Currently in development phase, so as of now, I'm just testing with a dummy static data within GSP, but when the database and the backend is ready, I'm planning to replace the dummy data with fetch pointing to an API endpoint.

Collapse
 
snakepy profile image
Fabio

Hey I am currently trying to implement this into next 13.4 and I have troubles implementing the part where I would use Component.requireAuth, because in the new NextJs set up the component is not injected into the global layout. Any idea on how this could be refactored?

Collapse
 
alonl profile image
Alon Lavi

Thanks for this post!
Just a note for people who use Auth0 - you can use withPageAuthRequired from the nextjs-auth0 library.

Collapse
 
matd1 profile image
MatD1

This is awesome, Is there any chance this can be changed to js, I have never used typescript and I am unsure how to convert the two. Sorry this may seem silly but I am rather new to this stuff

Collapse
 
ivandotv profile image
Ivan V.

Just convert typescript files to javascript file and it will work :)

Collapse
 
ramirezsandin profile image
Jorge

Nice article. How much better would it be to use this approach instead of a hoc component and wrap the exported page that you want to protect?

Collapse
 
ivandotv profile image
Ivan V. • Edited

I don't think it would be any better, there is no added functionality if you go that way, I also think that the code would look more convoluted.

Collapse
 
cn_d_ profile image
Cal

Nice pattern, thanks for writing this up. I just noticed that in the linked example, the browsers back button no longer works when going onto a protected page but not logging in.

Collapse
 
ivandotv profile image
Ivan V.

It works, but the router redirects you back to sign in immediately ( you can see it in the URL bar for a brief moment). That is a UX problem. I have chosen to redirect to sign when a non-authenticated user lands on the protected page immediately. You could instead of a redirect, show the button to login (on the protected page)