User Authentication in Next.js with Strapi
Tags: nextjs, jamstack, auth0, javascript
Published: 2022-02-22 14:28:45

---

canonical_url: https://strapi.io/blog/user-authentication-in-next-js-with-strapi?utm_source=dev.to&utm_medium=post&utm_id=blog

---

In this tutorial, we'll be building a [Next.js](https://strapi.io/integrations/nextjs-cms) application and authenticate that with [Strapi](https://strapi.io/) and [NextAuth](https://next-auth.js.org/).


# Introduction

[Strapi](https://strapi.io/) is the leading open-source headless CMS. It's 100% Javascript, fully customizable, and developer-first. I've been using Strapi for some of my [Open Source projects](https://github.com/ghoshnirmalya), and the developer experience is excellent. It has helped me build prototypes and products much faster.

[Next.js](https://strapi.io/integrations/nextjs-cms) is a [React](https://strapi.io/integrations/react-cms) framework for building Server-side rendered applications. It has many features with a good developer experience and supports TypeScript out of the box.

[NextAuth](https://next-auth.js.org/) is an authentication library built for use with Next.js. It's easy, fast, and secure.

The code for this tutorial is available on [GitHub](https://github.com/ghoshnirmalya/nextjs-authentication-using-strapi-and-next-auth).


# Software Required to Run the Application
1. [Docker](https://www.docker.com/) ([Click here to d](https://docs.docker.com/get-docker/)[ownload](https://docs.docker.com/get-docker/)[.](https://docs.docker.com/get-docker/))
2. [npm](https://www.npmjs.com/) ([Click here to d](https://nodejs.org/en/download/)[ownload](https://nodejs.org/en/download/)[.](https://nodejs.org/en/download/))
3. [yarn](https://classic.yarnpkg.com/) ([Click here to d](https://classic.yarnpkg.com/en/docs/install/#mac-stable)[ownload](https://classic.yarnpkg.com/en/docs/install/#mac-stable)[.](https://classic.yarnpkg.com/en/docs/install/#mac-stable))


# Creating a New Next.js Application

Let's start by creating a new Next.js application. We can create a Next.js application using the following command:

```shell
    yarn create next-app
```

The above command will ask for the name of the project. We'll call it “frontend”.

Once the setup of the project and installing all dependencies are complete, we can go inside the frontend directory and start the application using the following command:

```shell
    cd frontend && yarn dev
```

The above command will start the application on [http://localhost:3000/](http://localhost:3000/).


![Next.js Default Home Page](https://d2zv2ciw0ln4h1.cloudfront.net/uploads/s_3_CA_45_A42_FBE_54_E8_C3_DBE_537_C7_DB_5_ED_734_AA_98969688_E39_DE_1_ABD_28_E204_BC_590_D_1603696450663_screely_1603696445310_1195100074.png)


# Creating a New Strapi Application

In this section, we'll create a new Strapi application using [Docker](https://www.docker.com/). [More information about how to create a new Strapi application using Docker can be obtained from their repository.](https://github.com/strapi/strapi-docker) We'll use [Postgres](https://www.postgresql.org/) to do this.

We can create a new directory and name it “backend” in the root of our project. We can create a new file `docker-compose.yml` inside the backend directory with the following content:


    # backend/docker-compose.yml
    
    version: '3'
    services:
      strapi:
        container_name: strapi
        image: strapi/strapi
        environment:
          - DATABASE_CLIENT=postgres
          - DATABASE_HOST=db
          - DATABASE_PORT=5432
          - DATABASE_NAME=strapi
          - DATABASE_USERNAME=strapi
          - DATABASE_PASSWORD=strapi
        ports:
          - 1337:1337
        volumes:
          - ./app:/srv/app
        depends_on:
          - db
      db:
        container_name: postgres
        image: postgres
        restart: always
        volumes:
          - ./db:/var/lib/postgresql/data
        ports:
          - 5432:5432
        environment:
          POSTGRES_USER: strapi
          POSTGRES_PASSWORD: strapi
          POSTGRES_DB: strapi

Now, we need to start Docker and run the following command inside the backend directory to create our new Strapi application:

```shell
    docker-compose up
```


- When running this image, Strapi will check if there is a project in the `/srv/app` folder of the container. If there is nothing, it will run the [S](https://strapi.io/documentation/v3.x/cli/CLI.html#strapi-new)[trapi new command](https://strapi.io/documentation/v3.x/cli/CLI.html#strapi-new) in the container `/srv/app` folder.


![Strapi Admin Console](https://paper-attachments.dropbox.com/s_503485BC0604981C01602F795632328FE6EB32BEAA3F420468854A65A271C965_1639224849346_Screenshot+from+2021-12-11+11-59-29.png)


Once the setup of our Strapi application is complete, we'll be able to view the administration panel at [http://localhost:1337/admin](http://localhost:1337/admin).

Next, we'll need to create our first administrator in order to log into the Strapi administration panel:


![Strapi Admin Registration](https://paper-attachments.dropbox.com/s_503485BC0604981C01602F795632328FE6EB32BEAA3F420468854A65A271C965_1639224879838_localhost_1337_admin_auth_register-admin+3.png)


Once we create our first administrator, we'll be logged into the Strapi administration panel:


![Strapi Admin Dashboard Home Page](https://paper-attachments.dropbox.com/s_503485BC0604981C01602F795632328FE6EB32BEAA3F420468854A65A271C965_1639224896938_localhost_1337_admin_auth_register-admin+4.png)



# Creating and Integrating Google OAuth Client into our Applications

In this section, we'll create a new [Google OAuth Client](https://console.developers.google.com/apis/credentials/oauthclient) and integrate it into Next.js and Strapi applications.

First, we'll need to visit the [Google Developer Console](https://console.developers.google.com/apis/credentials/oauthclient) to create a new OAuth Client and copy the credentials (Client ID and Client Secret) in our `frontend/**.env**` file:


1. Create a new **OAuth client ID**.
2. Choose “web application” as the **application type**.
3. Add the following **authorized redirect URLs**:


- `http://localhost:3000/api/auth/callback/google`
- `http://localhost:1337/connect/google/callback`


![Callback URL Settings](https://d2zv2ciw0ln4h1.cloudfront.net/uploads/s_3_CA_45_A42_FBE_54_E8_C3_DBE_537_C7_DB_5_ED_734_AA_98969688_E39_DE_1_ABD_28_E204_BC_590_D_1603717222850_screely_1603717219342_1dceb50c82.png)


Once we click on the save button, we'll get our new OAuth Client's credentials. We can create a new file `.env` inside our frontend directory to store all the credentials:


    // frontend/.env
    
    NEXT_PUBLIC_API_URL=http://localhost:1337
    NEXT_PUBLIC_DATABASE_URL=postgres://strapi:strapi@localhost:5432/strapi?synchronize=true
    NEXTAUTH_URL=http://localhost:3000
    GOOGLE_CLIENT_ID="12345.apps.googleusercontent.com"
    GOOGLE_CLIENT_SECRET="1234-567-9"

You'll need to replace the values of `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` with the values of your new Google OAuth Client.

Next, let's add these credentials to our Strapi application as well. In the Strapi administration panel, we need to add the Google OAuth Client credentials and enable the **Google provider.** The values can be added in the **Providers** menu inside the **Settings** tab.

We need to enter the **Client ID** and **Client Secret** in the **Google provider** and **enable** that:


![Google Login Provider](https://paper-attachments.dropbox.com/s_503485BC0604981C01602F795632328FE6EB32BEAA3F420468854A65A271C965_1639225075272_localhost_1337_admin_auth_register-admin+7.png)



# Installing and Integrating NextAuth with Next.js and Strapi

In this section, we'll be [installing and integrating NextAuth](https://next-auth.js.org/).

We can run the following command inside our frontend directory to install NextAuth as a dependency:

```shell
    yarn add next-auth
```

Next, we'll need to create a new file, `...nextauth.js`, inside `frontend/pages/api/auth` directory with the following content:

    // frontend/pages/api/auth/[...nextauth].js
    
```js
    import NextAuth from "next-auth";
    import Providers from "next-auth/providers";
    
    const options = {
      providers: [
        Providers.Google({
          clientId: process.env.GOOGLE_CLIENT_ID,
          clientSecret: process.env.GOOGLE_CLIENT_SECRET,
        }),
      ],
      database: process.env.NEXT_PUBLIC_DATABASE_URL,
      session: {
        jwt: true,
      },
      callbacks: {
        session: async (session, user) => {
          session.jwt = user.jwt;
          session.id = user.id;
          return Promise.resolve(session);
        },
        jwt: async (token, user, account) => {
          const isSignIn = user ? true : false;
          if (isSignIn) {
            const response = await fetch(
              `${process.env.NEXT_PUBLIC_API_URL}/auth/${account.provider}/callback?access_token=${account?.accessToken}`
            );
            const data = await response.json();
            token.jwt = data.jwt;
            token.id = data.user.id;
          }
          return Promise.resolve(token);
        },
      },
    };
    
    const Auth = (req, res) =>
      NextAuth(req, res, options);
    
    export default Auth;
```

In the [NextAuth callback](https://next-auth.js.org/configuration/options#callbacks) function, we're calling the [Strapi Authentication API endpoint](https://strapi.io/documentation/v3.x/plugins/users-permissions.html#authentication). We're storing the JWT (`token.jwt`) and user ID (`data.user.id`) from the data that the Strapi API sends us. 

In this way, we can understand which user is currently authenticated.

We can get the details of the authenticated users from the `[getSession](https://next-auth.js.org/getting-started/client#getsession)` [function of NextAuth](https://next-auth.js.org/getting-started/client#getsession). If the `getSession` function doesn't return us any details, we can assume that the user is not authenticated.

We'll also need to add the [pg](https://www.npmjs.com/package/pg) package, so that NextAuth can connect to our database directly. We can install that package using the following command from our frontend directory:
`yarn add pg`

We can verify whether NextAuth is working with our application by updating our `frontend/pages/index.js` with the following content:


    // frontend/pages/index.js
    
```js
    import { getSession, signIn, signOut } from "next-auth/client";
    import Head from 'next/head';
    import Link from "next/link";
    import React from "react";
    
    const IndexPage = ({
      session,
    }) => {
      const signInButtonNode = () => {
        if (session) {
          return false;
        }
    
        return (
          <div>
            <Link href="/api/auth/signin">
              <button
                onClick={(e) => {
                  e.preventDefault();
                  signIn();
                }}
              >
                Sign In
              </button>
            </Link>
          </div>
        );
      };
    
      const signOutButtonNode = () => {
        if (!session) {
          return false;
        }
    
        return (
          <div>
            <Link href="/api/auth/signout">
              <button
                onClick={(e) => {
                  e.preventDefault();
                  signOut();
                }}
              >
                Sign Out
              </button>
            </Link>
          </div>
        );
      };
    
      if (!session) {
        return (
          <div className="hero">
            <div className="navbar">
              {signOutButtonNode()}
              {signInButtonNode()}
            </div>
            <div className="text">
              You aren't authorized to view this page
            </div>
          </div>
        )
      }
    
      return (
        <div className="hero">
          <Head>
            <title>Index Page</title>
          </Head>
          <div className="navbar">
            {signOutButtonNode()}
            {signInButtonNode()}
          </div>
          <div className="text">
            Hello world
          </div>
        </div>
      );
    };
    
    export const getServerSideProps = async ({ req }) => {
      const session = await getSession({ req });
      return {
        props: {
          session,
        },
      };
    };
    
    export default IndexPage;
```

Now, if we visit [http://localhost:3000/](http://localhost:3000/), we should be able to view the following screen:


![Next.js Sign In Page](https://d2zv2ciw0ln4h1.cloudfront.net/uploads/s_3_CA_45_A42_FBE_54_E8_C3_DBE_537_C7_DB_5_ED_734_AA_98969688_E39_DE_1_ABD_28_E204_BC_590_D_1603726661880_screely_1603726655803_db12436eff.png)


We can log in using our Gmail account once we click on the **Sign In** button. Once we're signed in, we should be able to view the following screen on [http://localhost:3000/](http://localhost:3000/):


![Next.js Protected Page](https://d2zv2ciw0ln4h1.cloudfront.net/uploads/s_3_CA_45_A42_FBE_54_E8_C3_DBE_537_C7_DB_5_ED_734_AA_98969688_E39_DE_1_ABD_28_E204_BC_590_D_1603726755418_screely_1603726749303_d5cf662fab.png)


All the details of the authenticated user are present in the **session** prop of the page:


![Next.js Sign out Page](https://d2zv2ciw0ln4h1.cloudfront.net/uploads/s_3_CA_45_A42_FBE_54_E8_C3_DBE_537_C7_DB_5_ED_734_AA_98969688_E39_DE_1_ABD_28_E204_BC_590_D_1603726884436_screely_1603726852445_0256760dc4.png)


We can show the details of the authenticated user by fetching the details from the **session** prop. Also, the authenticated user will now be visible in the Strapi administration panel:


![Strapi User Database](https://paper-attachments.dropbox.com/s_503485BC0604981C01602F795632328FE6EB32BEAA3F420468854A65A271C965_1639224556441_localhost_1337_admin_auth_register-admin+10.png)



# Conclusion

In this tutorial, we learned how we can authenticate a Next.js application using Strapi and NextAuth. We've worked with the [REST API](https://strapi.io/documentation/v3.x/content-api/api-endpoints.html) that Strapi provides out of the box. However, a similar solution can also be implemented for using [GraphQL](https://strapi.io/documentation/v3.x/plugins/graphql.html#usage).

The code for this tutorial is available on [GitHub](https://github.com/ghoshnirmalya/nextjs-authentication-using-strapi-and-next-auth). I've also created a [boilerplate for using Strapi with Next.js](https://github.com/ghoshnirmalya/nextjs-strapi-boilerplate). It'll help you get up and running with Strapi and Next.js really quickly. Feel free to give it a try.

Get started with Strapi by creating a project using a [starter](https://strapi.io/starters) or trying our [live demo](https://strapi.io/demo). Also, consult our [forum](https://forum.strapi.io/) if you have any questions. We will be there to help you.