Authentication is a crucial aspect of any web application, including those built with Next.js. There are several ways to manage authentication in Next.js, and in this blog post, I will explain how to implement email-based authentication with JWT tokens using NextAuth.
To begin with, you will need to set up an external database. You can choose a local database or a cloud-based one. In my case, I opted for PostgreSQL, but you can use any database that you prefer.
Assuming that you already have a Next.js website up and running, the first step is to install the NextAuth and PostgreSQL library by running the following command:
npm install next-auth pg
After that, you need to add the necessary environment variables to your .env
file:
DATABASE_URL=<enter URL of the postgresql:// database>
EMAIL_SERVER=smtp://user:[email protected]:465
EMAIL_FROM=Your name <[email protected]>
NEXTAUTH_URL=http://localhost:3000
SECRET=<your secret code>
Make sure to generate a secret code, which you can do using a tool like https://generate-secret.vercel.app/32.
During the setup process, it can be helpful to use a service like https://mailtrap.io to test the email functionality.
Next, create a file named pages/api/auth/[...nextauth].js
with the following content:
import NextAuth from 'next-auth'
import Providers from 'next-auth/providers'
export default NextAuth({
providers: [
Providers.Email({
server: process.env.EMAIL_SERVER,
from: process.env.EMAIL_FROM,
}),
],
database: process.env.DATABASE_URL,
secret: process.env.SECRET,
session: {
jwt: true,
maxAge: 30 * 24 * 60 * 60, // 30 days
},
jwt: {
secret: 'INp8IvdIyeMcoGAgFGoA61DdBglwwSqnXJZkgz8PSnX', //use a random secret token here
encryption: true,
},
debug: true,
})
This code sets up the authentication providers, database connection, session settings, and JWT configurations. You may need to modify the code based on your data access layer. If you are using the Prisma ORM, you can also install the @next-auth/prisma-adapter
package and include it in the […]nextauth].js
file. Don’t forget to add the necessary models to your schema.prisma
file.
To integrate NextAuth with your Next.js app, open the pages/_app.js
file and add the following import statement:
import { SessionProvider } from 'next-auth/react'
Then, wrap the <Component />
call with the SessionProvider
component:
return (
<SessionProvider session={pageProps.session}>
<Component {...pageProps} />
</SessionProvider>
)
Now, you can add a link in your app that points to /api/auth/signin
. This link will serve as the login form for your users.
If you want to restrict access to certain pages and require a user to be logged in, you can import the useSession
hook from next-auth/react
. You can use this hook to check the session state and render appropriate content based on the user’s authentication status.
import { useSession } from 'next-auth/react'
const MyComponent = () => {
const { data: session, status } = useSession()
if (typeof window !== 'undefined' && loading) return null
if (typeof window !== 'undefined' && !session) {
router.push('/api/auth/signin')
}
if (!session) { //for server-side rendering
return null
}
return (
<>
{session && (
<p>
{session.user.email}{' '}
<button
className="underline"
onClick={() => {
signOut()
router.push('/')
}}
>
logout
</button>
</p>
)}
{/* Render your authenticated content here */}
</>
)
}
In this example, we check if the session exists and render the user’s email and a logout button if the session is active. If the session is not established, we redirect the user to the login page. You can customize this logic based on your specific requirements.
That’s it! You have now successfully implemented email-based authentication with JWT tokens using NextAuth in your Next.js app. NextAuth provides a comprehensive set of features and customization options, so be sure to explore the documentation at https://next-auth.js.org.