In this post we setup OAuth between a NextJS client and an Express API. I have assumed knowledge of JavaScript, Nodejs and Expressjs in this post. I, however, explain things well enough for anyone to catch up and understand things.

This post is composed of two parts.

API - Involves the REST API backend part which has the OAuth collection of endpoints and a delete profile endpoint. This will involve creating REST endpoints, a GitHub OAuth and a MongoDB database for storing user details. UI - This part includes setting a Nextjs Server Side Rendered application that has a single page for doing log in.

So to make OAuth work take a look at the diagram below.

User clicks the login button which calls our API /auth/github . Our API uses the GitHub passport library to redirect the user to their GitHub account to either approve or decline the authentication. After the user approves the authentication, Passportjs will call back our auth callback endpoint /auth/github/callback with the user details. We then use the user details to generate a token that we redirect the user back to our UI with and complete the authentication process.

Run npm init to create a new Nodejs app.

Install packages express , body-parser , passport , passport-github , jsonwebtoken and mongoose that make up our API server.

npm i --save express passport passport-github mongoose jsonwebtoken

Our base server will look like this. Using body-parser to parse request body and listen on port 3001.

Let's allow cors so that our UI will be able to call the API without cross-origin requests restrictions. This will be a middleware that mounts in the apps request chain.

The next thing we do at this point is to set up passport to serialize the user for the downstream process. Passport will serialize user upon receiving the OAuth response then leave everything to us. We will handle session and auth ourselves using cookie after OAuth is negotiation is done.

So the above code will be used by the communication between passport and passport-github Now its time to setup OAuth part that will talk to Github API which will comprise the login endpoint. For this, we will use a dedicated route /auth and some database utilities using Mongoose for storing our user details from the OAuth call.

Setup the Data layer

This comprises anything you like but I am using Mongoose to connect to a local mongodb. Mongoose is useful for setting up quick connections and models.

Start the db service connection when the app starts. Edit app.js and require db.

Then we create the user model. Comprising just the oAuthId - The user id on GitHub and oAuthData - The rest of the data.

Next, we create the DB utilities for creating and getting our user from Mongodb

Now we are ready to create our auth endpoints. But before that go to GitHub OAuth Apps settings and create a new app. Get the values Client ID and Client Secret and set to the local environment as below

Now create the file below that holds the endpoints that login calls and intern calls GitHub APIs for us. Here we call GitHub and authenticate then generate a new token that we send back to the UI in the URL query

And the we mount the route to our app, edit app.js and add route.

Our API is now ready to start accepting OAuth requests

Create a new Nextjs app using npx create-next-app and follow the instructions. After creating a nextjs app, we will edit the index page to have a Login button.

Now at this point clicking login should redirect number of times and lead us back to the index page with a cookie called authorization in the browsers cookie section. So the next thing we do is to find this cookie when serving our page using Nextjs server.

To set the cookie, as the token is sent in the redirect URL after login, we use a custom Document in our Next app. This will help us intercept the request on the server side and set the cookie using Nookies

For reading the cookie on the server side, we use Nookies to read the token while also considering it in the request query parameters.

npm install — save nookies

Then we add a getInitialProps to our index page component to read the cookie.

Now after successful login, the login should no show because during the server side rendering process, we find the cookie and return in as a prop to the component to be used in any subsequent requests to the API. Lets use the token to get the user profile.

Now we know that the cookie is available during server side rendering an so we can use it to do API calls that require authentication like getting user profile for example.

For this we add an endpoint to the user profile

And mounted on the app.

Then we modify the index page to get the user while being server-side rendered. We use the token that is taken from cookies in get initial props or from query.

I hope you have learned something in this post. We have used cookies to manage authentication on to a REST API that uses passportjs to authenticate to GitHub. You can use this method to authenticate to any other OAuth API like Google, Twitter, and Facebook.

The entire code used here is on GitHub Cheers!