Using next-auth for Authentication in Next.js App (Beginners Guide)

 Using next-auth for Authentication in Next.js App
(Beginners Guide)



Assuming that you have the basic idea of creating your first Next.js app. If you want to learn how to create your first Next.js app, go to Create your First Next.js App blog.


Get Started:

Clone the starter project file from the below GitHub link.

https://github.com/SantoshDawanse/next-auth-example/tree/starter


To clone this project, go to the folder where you want to place your project and open the terminal there. Now enter the following command in your terminal.


git clone https://github.com/SantoshDawanse/next-auth-example.git 


Now, install dependencies using the following command.


npm install


To run the development server


npm run dev


Now the Next.js app is running in http://127.0.0.1:3000/ .


Create Simple Template:

I am using a bootstrap example template for a client-side. Here is the link. https://getbootstrap.com/docs/4.0/examples/cover/ 


In the project’s root folder create a components folder. Inside that we are going to create Layout.js, Header.js and Footer.js files.


First, let’s create a Header.js file inside the components folder. The Header.js file will look like this.


    

    const Header = () => {

      return (

        <header className="masthead mb-auto">

          <div className="inner">

            <h3 className="masthead-brand">Dawnsoft</h3>

            <nav className="nav nav-masthead justify-content-center">

              <a className="nav-link active" href="#">Home</a>

              <a className="nav-link" href="#">Features</a>

              <a className="nav-link" href="#">Contact</a>

            </nav>        

          </div>

        </header>

      )

    }

 

    export default Header;

 


Similarly, let’s create a Footer.js file inside the components folder and it will look like this.


    

    const Footer = () => {

      return (

        <footer className="mastfoot mt-auto text-center">

          <div className="inner">

            <p>Next auth example, by 

        <a href="https://thedawnsoft.blogspot.com">dawnsoft</a>.

      </p>

          </div>

        </footer>

      )

    }

 

    export default Footer;

 


Now create a Layout.js file inside a components folder. Consider this as a main file and we’ll inject all other files inside this.


 

    import Head from "next/head"

    import Footer from "./Footer"

    import Header from "./Header"

 

    const Layout = ({children}) => {

      return (

        <>

          <Head>

            <title>Create Next App</title>

            <meta name="description" content="Generated by create next app" />

            <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossOrigin="anonymous" />

            <link rel="icon" href="/favicon.ico" />

          </Head>

          <main id="main" className="cover-container d-flex h-100 p-3 mx-auto flex-column">

            <Header />

            {children}

            <Footer />

          </main>

        </>

      )

    }

 

    export default Layout;



Now let's edit our styles. By default, inside the styles folder globals.css file is created. I am going to edit this file and after editing the globals.css file will look like this.


    

    html,

    body {

      height: 100%;

      background-color: #333;

      padding: 0;

      margin: 0;

      font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,

        Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;

    }

 

    a {

      color: inherit;

      text-decoration: none;

    }

 

    * {

      box-sizing: border-box;

    }

 

    body {

      display: -ms-flexbox;

      display: -webkit-box;

      display: flex;

      -ms-flex-pack: center;

      -webkit-box-pack: center;

      justify-content: center;

      color: #fff;

      text-shadow: 0 .05rem .1rem rgba(0, 0, 0, .5);

      box-shadow: inset 0 0 5rem rgba(0, 0, 0, .5);

    }

 

    .cover-container {

      max-width: 90%;

    }

 

    .masthead {

      margin-bottom: 2rem;

    }

 

    .masthead-brand {

      margin-bottom: 0;

    }

 

    .nav-masthead .nav-link {

      padding: .25rem 0;

      font-weight: 700;

      color: rgba(255, 255, 255, .5);

      background-color: transparent;

      border-bottom: .25rem solid transparent;

    }

 

    .nav-masthead .nav-link:hover,

    .nav-masthead .nav-link:focus {

      border-bottom-color: rgba(255, 255, 255, .25);

    }

 

    .nav-masthead .nav-link + .nav-link {

      margin-left: 1rem;

    }

 

    .nav-masthead .active {

      color: #fff;

      border-bottom-color: #fff;

    }

 

    @media (min-width: 48em) {

      .masthead-brand {

        float: left;

      }

      .nav-masthead {

        float: right;

      }

    }

 

    /*

    * Cover

    */

    .cover {

      padding: 0 1.5rem;

    }

    .cover .btn-lg {

      padding: .75rem 1.25rem;

      font-weight: 700;

    }

    /*

    * Footer

    */

    .mastfoot {

      color: rgba(255, 255, 255, .5);

    }

 


And let’s edit our index.js file too. After editing the file will look like this.


 

    import Layout from '../components/Layout'

 

    const Home = () => {

      return (

        <Layout>

          <main role="main" className="inner cover" style={{}}>

            <h1 className="cover-heading">Cover your page.</h1>

            <p className="lead">Cover is a one-page template for building simple and beautiful home pages. Download, edit the text, and add your own fullscreen background photo to make it your own.</p>

            <p className="lead">

              <a href="#" className="btn btn-lg btn-secondary">Learn more</a>

            </p>

          </main>

        </Layout>

      )

    }

 

    export default Home;


Upto now I have set up a Next.js app with a client-side template. Here is the github link for the code https://github.com/SantoshDawanse/next-auth-example/tree/template.


Add Next-Auth for Authentication:

First install the next-auth package using npm or yarn.


//using npm
npm install --save next-auth

//or using yarn
yarn add next-auth


Create a .env.local file in the root folder and inside that we are storing our GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET keys.


GOOGLE_CLIENT_ID=YOUR_GENERATED_GOOGLE_CLIENT_ID
GOOGLE_CLIENT_SECRET=YOUR_GENERATED_GOOGLE_CLIENT_SECRET


Now, inside the pages folder create an api folder and inside that create [...nextauth].js file. The created file will look like below.



 

 import NextAuth from "next-auth";

 import Providers from "next-auth/providers";

 

 export default NextAuth({

   debug: true,

   providers: [

     Providers.Google({

       clientId: process.env.GOOGLE_CLIENT_ID,

       clientSecret: process.env.GOOGLE_CLIENT_SECRET

     })

   ]

 })


To create GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET go to the https://console.cloud.google.com/apis/dashboard and create your own keys. If you have no idea how to create these keys, I have created a blog to create these, follow the blog Create CLIENT_ID and CLIENT_SECRET in Google


Now, let’s add the login and logout menu in the Header.js file. The updated Header.js file will look like this. 


 

    import { signIn, signOut, useSession } from "next-auth/client";

 

    const Header = () => {

 

      const [session] = useSession();

 

      if (session) {

         console.log(session); 

       }

 

      return (

        <header className="masthead mb-auto">

          <div className="inner">

            <h3 className="masthead-brand">Dawnsoft</h3>

            <nav className="nav nav-masthead justify-content-center">

              <a className="nav-link active" href="#">Home</a>

              <a className="nav-link" href="#">Features</a>

              <a className="nav-link" href="#">Contact</a>

              {

                !session && <button className="btn btn-outline-primary mx-2" onClick={() => {signIn()}}>Login</button>

              }

              {

                session && <button className="btn btn-outline-primary mx-2" onClick={() => {signOut()}}>Logout</button>

              }

              

            </nav>        

          </div>

        </header>

      )

    }

 

    export default Header;


Now, Login with Google is successfully integrated with the Next-Auth package. You can find the complete code here https://github.com/SantoshDawanse/next-auth-example/tree/next-google.   Here the default login and logout default page are used. I will cover custom pages with custom backend in my next blog.


Authentication in Next.js with Next-Auth Package




Post a Comment

Previous Post Next Post