Implementing Authentication In Next.js Using Next Auth

Raghav Mrituanjaya

Cover Image for Implementing Authentication In Next.js Using Next Auth

In this post, we will be implementing GitHub, Twitter and email authentication in Next JS using NextAuth.js

What is Next Auth?

NextAuth.js is a complete open-source authentication solution for Next.js applications. It has built-in hooks that let you access the user from the client side.

Getting Started

  1. I assume that you have maltreated created/initiated your next js project if not, just run yarn create next-app to create next js boilerplate code
  2. Now, we can install next-auth by running  yarn add next-auth or npm install next-auth
  3. Now, we can create an API route for the authentication by editing the pages/api/auth/[...nextauth].js file
import NextAuth from "next-auth"
import GithubProvider from "next-auth/providers/github"

export const authOptions = {
  // Configure one or more authentication providers
  providers: [
    GithubProvider({
      clientId: process.env.GITHUB_ID,
      clientSecret: process.env.GITHUB_SECRET,
    }),
    // ...add more providers here
  ],
}

export default NextAuth(authOptions)
  • You might need a provider which is a database. For this instance, I will be using the MongoDB

4. Now, we can access the user from the client side  by wrapping our component pages/_app.jsx with SessionProvider

import { SessionProvider } from "next-auth/react"

export default function App({
  Component,
  pageProps: { session, ...pageProps },
}) {
  return (
    <SessionProvider session={session}>
      <Component {...pageProps} />
    </SessionProvider>
  )
}

3. Now, we'll create a simple home page by editing pages/index.js

import { Center, VStack, Text, Button } from '@chakra-ui/react';
import { useSession, signIn } from 'next-auth/react';
import React from 'react';

export default function Home() {
    const { data } = useSession();
    return (
        <Center height="100%" my={'10rem'}>
            <VStack>
                <Text fontSize={'2xl'}>
                    Current User: {data?.user?.email || 'None'}{' '}
                </Text>

                {!data?.user && <Button onClick={() => signIn()}>Login</Button>}
            </VStack>
        </Center>
    );
}

4. Let's create an authentication page(pages/auth.js) where the users will be able to log in/Register using OAuth Providers like GitHub, discord

import {
    Box,
    Center,
    Container,
    Flex,
    Icon,
    VStack,
    Button,
} from '@chakra-ui/react';
import {
    getProviders,
    getSession,
    GetSessionParams,
    signIn,
    useSession,
} from 'next-auth/react';
import { FcGoogle } from 'react-icons/fc';
import { FaDiscord, FaGithub } from 'react-icons/fa';
import { GetServerSideProps } from 'next';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
export default function SignIn({ providers }) {
    const router = useRouter();
    const user = useSession();
    useEffect(() => {
        // if (router.query.callbackUrl) {
        //     router.push(router.query.callbackUrl as string);
        // }
        if (user?.data?.user) {
            router.push('/');
        }
    });
    let icons = [
        {
            name: 'Google',
            icon: FcGoogle,
        },
        {
            name: 'Github',
            icon: FaGithub,
        },
        {
            name: 'Discord',
            icon: FaDiscord,
        },
    ];
    return (
        <Flex h="100vh" alignItems={'center'} justifyContent="center">
            <Box
                border="1px"
                borderColor="gray.200"
                p={4}
                rounded="xl"
                // translateY={'50%'}
            >
                <VStack>
                    {Object.values(providers).map((provider: any) => (
                        <Button
                            leftIcon={
                                <Icon
                                    as={
                                        icons.find(
                                            (i) =>
                                                i.name.toLowerCase() ===
                                                provider.name.toLowerCase()
                                        ).icon
                                    }
                                />
                            }
                            onClick={async () => signIn(provider.id)}
                            key={provider.id}
                        >{`Sign in with ${provider.name}`}</Button>
                    ))}
                </VStack>
            </Box>
        </Flex>
    );
}

export const getServerSideProps: GetServerSideProps = async (context) => {
    const session = await getSession(context);
    const providers = await getProviders();
    // console.log(context.query);
    if (session) {
        return {
            redirect: {
                destination: (context?.query?.callbackUrl as string) || '/',
                permanent: false,
            },
        };
    }
    return {
        props: { providers },
    };
};

5. You may use the useSession() hook to obtain the user details on the client side or you may use getSession() on the server side

Client-Side

import { useSession } from "next-auth/react"

export default function Component() {
  const { data: session, status } = useSession()

  if (status === "authenticated") {
    return <p>Signed in as {session.user.email}</p>
  }

  return <a href="/api/auth/signin">Sign in</a>
}

Server-side

async function myFunction() {
  const session = await getSession() 
  /* ... */
}

6. We have successfully now added authentication to our next js site, you may now run yarn dev and the dev server might start running

Conclusion  

  • I have used the Chakra UI library to style up the frontend
  • Full source code is available on GitHub

P.S:- Vultr(Get a $100 credit by registering using this link) is an excellent hosting choice if you're looking for one.

Buy Me A Coffee
Implementing Authentication In Next.js Using Next Auth cover image

Raghav Mrituanjaya

· min read

What Is Terraform CDK? - Terraform code in JavaScript cover image

Programming

What Is Terraform CDK? - Terraform code in JavaScript

A small introduction to hashicorp terraform CDK like its uses, advantages, and a small code written ...

Raghav Mrituanjaya

· min read

Cool Features Of Next JS 12 cover image

Programming

Cool Features Of Next JS 12

How Ghost allows you to turn anonymous readers into an audience of active subscribers, so you know w...

Raghav Mrituanjaya

· min read


© 2022

THE GOGAMIC BLOG