Within this 7 minute video we will add authentication to the default next.js template with Auth0. This includes installing the nextjs-auth0 npm package, configuring your Auth0 account, creating API endpoints, adding login / logout buttons, and pulling user data from an authenticated user session (by using the native getServerSideProps function)!
Tyler Clark: [0:00] I'm going to start with a blank next.js template. If you already have a site ready, then that should work as well. After everything installs, I'm going to run npm run dev. This is the one I'm going to be starting with.
[0:11] Step one is going to be installing the nextjs-auth0 npm package into our project. This SDK will give us the functionality we need in order to integrate Auth0 into our app. With that package installed, we can create a runtime configuration that's going to define the boilerplate needed to configure our Auth0 account inside of our next.js app.
[0:32] Back in our project, let's create a utils folder and within that, an auth0.js file. I'll paste in some of those config stuff that we saw on the npm GitHub page. We don't have anything in config files, so delete that line. Notice that we need to update some of these items with values from a Auth0 account.
[0:51] Head over to auth0.com and either log in or sign up for a new account. Once that loads, it's going to show you your dashboard. Click on applications here on the left. Create a new application and then select Single Page Web App and give it a good name.
[1:05] Once you press Create, you're going to be redirected to a page that looks like this where it shows you a quick start. Go ahead and click on Settings. The items that we're looking for for our code is going to be Domain, Client ID and Client Secret.
[1:18] Before we do that, let's look at something else we need to do. We also need to add Allowed Callback URLs, the API callback URL that we're going to be working with. Add that here. Also add localhost:3000 to Allowed Logout URL and to Allowed Web Origins. Back inside of our code, let's add the Domain Client ID and Client Secret to our config information.
[1:42] It's not imperative that we not commit the Domain and Client ID into our main repo where other people can see because these don't need to be hidden. We should hide the Client Secret from our repo source code. I'm going to create a .env file and add that value there, and then use it inside of our auth0.js file.
[2:00] As you can see, we also need to generate a random 64-character secret for our cookies. I'm doing that with OpenSSL, which is built into next. Next, let's add this .env to our gitignore, and then head back over to our auth0.js file to add these new values to.
[2:16] Now all we need to do is write process.env, and then the value name we defined and the .env file. For Client Secret, it's AUTH0_CLIENT_SECRET. For our cookie secret, AUTH0_COOKIE_SECRET.
[2:29] Finally, let's delete the cookieDomain default option here so we don't have any trouble getting info out of the cookies later on. This is optional. As you can see here, when we leave it blank, it will restrict it to our domain. Perfect. That's pretty much it from the Auth0 side of what we need to do to set it up.
[2:45] Now let's set a login a tag to our index page that's just going to href to api/login. Let's npm run dev our site, and then look for that Login button. If we click on the Login button as it is now, we're going to get a 404 because this page doesn't exist just yet. Let's go ahead and create that. This just means we need to create a subfolder underneath pages and then a login.js file.
[3:09] I'm going to paste some code that I've already put together, and then walk you through what's happening here. Notice that we import our Auth0 boilerplate that we set up previously. This is going to give us the sdk npm package all configured and ready to go.
[3:23] We have this async function that will run when the API page is hit. Notice the try catch to help us with any error handling. In the try, we call this handleLogin function. If we're not able to login successfully, then we're going to return an error status.
[3:40] If we try to login in the UI, we're redirected to the Auth0 login popup. This is where we can sign if we already have an account, or sign up to create a new one. I have some social providers configured in my app, that is why you see those options there.
[3:53] Once clicking the Login button here, we see we get another 404. That's because back in our auth0.js file, we say that after successfully authenticating, we want to redirect to this Callback API page. This page doesn't exist, so let's create it.
[4:09] This is going to go underneath the api folder just like login. I'm going to paste some code in here where we're again importing auth0 from our utils file, another async function. We're going to call this handleCallback function on it, which does some cleanup and then redirects us to the root page.
[4:27] Now we'll try the Login button again. It'll see the valid session loading here that we made before we saw the 404 and will automatically redirect us to this home page, as an authenticated user. Perfect.
[4:39] Every login experience needs a logout. Let's go back to our index page. We're going to add a link to a logout page. We're going to say logout here and here, which means we need to create this page underneath our api folder, so logout.js.
[4:55] Very similar setup to the login. We're going to paste some code in here that's going to be referencing the auth0 file that we did. We're going to call this handleLogout function, which is going to do just as it says, log us out.
[5:09] Back inside of our UI, we can see how this looks. There's just a logout button underneath our login. By clicking that, you'll see that our page does some refreshing in the background, and we are now logged out. By clicking log in, we're going to be able to get the experience of logging in, which will redirect us back to our index page.
[5:27] Before we continue, let's do a quick recap. We installed the nextjs-auth0 npm package, added the necessary Auth0 app information to our auth0.js file which also included adding a .env file. This file here is going to hold the SDK functions that help us log in and log out on the two API pages we created, which are being referenced from the index page.
[5:51] Before we close, I want to do one more thing. Back inside the index.js page, down at the bottom, I'm going to use the getServerSideProps function, which is an async function. Here, I'm going to be getting information out of the login session.
[6:05] I'm going to say const session = await auth0.getSession passing through context.request. Then I'm going to return a object that has props that's an object of session. Back at the top, we need to now import auth0 from our utils file. We'll say import auth0 from the utils/auth0.js file. I'm going to pass through props. Then for now, just console.log that props from our component.
[6:38] Back inside of our UI, let's go ahead and refresh this page while being logged in to see what we get. Inside of our console, you see that we have this object with session. You're going to see that we get all the information of that user from the session that we can work with.
[6:53] When a user authenticates, we will automatically get their session info into our home component. Knowing that, we can be smart on when to show the login and logout buttons. Here, I'm just going to use a basic ternary and switch between login, logout depending on if we have a user or not.
Member comments are a way for members to communicate, interact, and ask questions about a lesson.
The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io
Be on-Topic
Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.
Avoid meta-discussion
Code Problems?
Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context
Details and Context
Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!