DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 968,873 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for Implementing Authentication In Next.js Using Next Auth
Raghav Mrituanjaya
Raghav Mrituanjaya

Posted on • Originally published at thegogamicblog.xyz on

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)

Enter fullscreen mode Exit fullscreen mode


javascript

  • You might need a provider which is a database. For this instance, I will be using the MongoDB
  1. 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>
  )
}

Enter fullscreen mode Exit fullscreen mode


javascript

  1. 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>
    );
}

Enter fullscreen mode Exit fullscreen mode


javascript

  1. 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 },
    };
};

Enter fullscreen mode Exit fullscreen mode


javascript

  1. 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>
}

Enter fullscreen mode Exit fullscreen mode

Server-side

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

Enter fullscreen mode Exit fullscreen mode
  1. 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.

Top comments (0)

"I made 10x faster JSON.stringify() functions, even type safe"

☝️ Must read for JS devs