Implementing Authentication In Next.js Using Next Auth

Implementing Authentication In Next.js Using Next Auth

Raghav MrituanjayaRaghav Mrituanjaya
3 min read
AD PLACEHOLDER

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.

AD PLACEHOLDER
javascriptnodejsnextjs

Subscribe to our Newsletter

AD PLACEHOLDER
Loading...
Loading...

Follow Us