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
- 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 - Now, we can install next-auth by running
yarn add next-auth
ornpm install next-auth
- 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
P.S:- Vultr(Get a $100 credit by registering using this link) is an excellent hosting choice if you're looking for one.