Making a Site with User Authentication
Sometimes, you need to create a site with gated content, restricted to only authenticated users. Using Gatsby, you may achieve this using the concept of client-only routes, to define which pages a user can view only after logging in.
Prerequisites
You should have already configured your environment to be able to use the gatsby-cli
. A good starting point is the main tutorial.
Security notice
In production, you should use a tested and robust solution to handle the authentication. Auth0, Firebase, and Passport.js are good examples. This tutorial will only cover the authentication workflow, but you should take the security of your app as seriously as possible.
Building your Gatsby app
Start by creating a new Gatsby project using the barebones hello-world
starter:
Create a new component to hold the links. For now, it will act as a placeholder:
And create the layout component that will wrap all pages and display navigation bar:
Lastly, change the index page to use layout component:
Authentication service
For this tutorial you will use a hardcoded user/password. Create the folder src/services
and add the following content to the file auth.js
:
The guide on adding authentication contains more information about the flow for connecting Gatsby to an external service.
Creating client-only routes
At the beginning of this tutorial, you created a “hello world” Gatsby site, which includes the @reach/router
library. Now, using the @reach/router library, you can create routes available only to logged-in users. This library is used by Gatsby under the hood, so you don’t even have to install it.
First, create gatsby-node.js
in root directory of your project. You will define that any route that starts with /app/
is part of your restricted content and the page will be created on demand:
Note: There is a convenient plugin that already does this work for you: gatsby-plugin-create-client-paths
Now, you must create a generic page that will have the task to generate the restricted content:
Next, add the components regarding those new routes. The profile component to show the user data:
The login component will handle - as you may have guessed - the login process:
Though the routing is working now, you still can access all routes without restriction.
Controlling private routes
To check if a user can access the content, you can wrap the restricted content inside a PrivateRoute component:
And now you can edit your Router to use the PrivateRoute component:
Refactoring to use new routes and user data
With the client-only routes in place, you must now refactor some files to account for the user data available.
The navigation bar will show the username and logout option to registered users:
The index page will suggest to log in or check the profile accordingly:
And the profile will show the user data:
You should now have a complete authentication workflow, functioning with both login and a user-restricted area!
Further reading
If you want to learn more about using production-ready auth solutions, these links may help:
- Gatsby repo simple auth example
- A Gatsby email application, using React Context API to handle authentication
- The Gatsby store for swag and other Gatsby goodies
- Building a blog with Gatsby, React and Webtask.io!
- JAMstack PWA — Let’s Build a Polling App. with Gatsby.js, Firebase, and Styled-components Pt. 2
- JAMstack Hackathon Starter - Authenticated Gatsby app starter with Netlify Identity
- Learn With Jason Livestream: How to use Netlify Identity and Netlify Functions (with Shawn Wang)