Next.js Email Authentication using NextAuth

Managing authentication in Next.js can be done in many different ways.

I chose to implement email-based authentication with JWT tokens via NextAuth.js

An external database is needed. I used https://railway.app to create it. I chose Postgres but you can use anything you want.

I suppose you already have a Next.js website up.

Run npm install next-auth pg to install NextAuth and the Postgres library.

Then add to your .env file:

USER_DATABASE_URL=<enter URL from Railway>

EMAIL_SERVER=smtp://user:pass@smtp.mailtrap.io:465

EMAIL_FROM=Your name 
<you@email.com>

NEXTAUTH_URL=http://localhost:3000

SECRET=

Make sure you add a SECRET code. Use https://generate-secret.vercel.app/32 to generate it.

I use https://mailtrap.io to test the emails, it’s quite handy.

Then create a pages/api/auth/[...nextauth].js file with this 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.USER_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,
})

Now open pages/_app.js and add

import { Provider } from 'next-auth/client'

And wrap your <Component /> call:

return <Component {...pageProps} key={router.asPath} />

with it:

return (
<Provider session={pageProps.session}>
  <Component {...pageProps} key={router.asPath} />
</Provider>
)

Now add where you want a link that points to /api/auth/signin. This will be the login form.

Finally, in pages you want to protect, you first import the useSession hook:

import { useSession } from 'next-auth/client'

Then you use that to gather information on the state. loading is true when the session info is still loading.

const [session, loading] = useSession()

We use that information to not return anything unless we finished loading, and unless the session is established:

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
}

I push to /api/auth/signin if the user is not logged in. You can also create a custom form if you want, but those are the basics.

That’s it! Super simple.

Now when the user enters the email in the form, the information is stored in the verification_requests table in the database. Once the email is verified, the user’s info is stored in the users table.

That database is not going to be read any more, until the user logs out and logs in again. The user has the JWT token stored in the cookies and that’s enough to authenticate.

The NextAuth package is very complete and provides tons of options and customizations, check them out.


This content originally appeared on flaviocopes.com and was authored by flaviocopes.com

Managing authentication in Next.js can be done in many different ways.

I chose to implement email-based authentication with JWT tokens via NextAuth.js

An external database is needed. I used https://railway.app to create it. I chose Postgres but you can use anything you want.

I suppose you already have a Next.js website up.

Run npm install next-auth pg to install NextAuth and the Postgres library.

Then add to your .env file:

USER_DATABASE_URL=<enter URL from Railway>

EMAIL_SERVER=smtp://user:pass@smtp.mailtrap.io:465

EMAIL_FROM=Your name 
<you@email.com>

NEXTAUTH_URL=http://localhost:3000

SECRET=

Make sure you add a SECRET code. Use https://generate-secret.vercel.app/32 to generate it.

I use https://mailtrap.io to test the emails, it’s quite handy.

Then create a pages/api/auth/[...nextauth].js file with this 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.USER_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,
})

Now open pages/_app.js and add

import { Provider } from 'next-auth/client'

And wrap your <Component /> call:

return <Component {...pageProps} key={router.asPath} />

with it:

return (
<Provider session={pageProps.session}>
  <Component {...pageProps} key={router.asPath} />
</Provider>
)

Now add where you want a link that points to /api/auth/signin. This will be the login form.

Finally, in pages you want to protect, you first import the useSession hook:

import { useSession } from 'next-auth/client'

Then you use that to gather information on the state. loading is true when the session info is still loading.

const [session, loading] = useSession()

We use that information to not return anything unless we finished loading, and unless the session is established:

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
}

I push to /api/auth/signin if the user is not logged in. You can also create a custom form if you want, but those are the basics.

That’s it! Super simple.

Now when the user enters the email in the form, the information is stored in the verification_requests table in the database. Once the email is verified, the user’s info is stored in the users table.

That database is not going to be read any more, until the user logs out and logs in again. The user has the JWT token stored in the cookies and that’s enough to authenticate.

The NextAuth package is very complete and provides tons of options and customizations, check them out.


This content originally appeared on flaviocopes.com and was authored by flaviocopes.com


Print Share Comment Cite Upload Translate Updates
APA

flaviocopes.com | Sciencx (2021-05-17T05:00:00+00:00) Next.js Email Authentication using NextAuth. Retrieved from https://www.scien.cx/2021/05/17/next-js-email-authentication-using-nextauth/

MLA
" » Next.js Email Authentication using NextAuth." flaviocopes.com | Sciencx - Monday May 17, 2021, https://www.scien.cx/2021/05/17/next-js-email-authentication-using-nextauth/
HARVARD
flaviocopes.com | Sciencx Monday May 17, 2021 » Next.js Email Authentication using NextAuth., viewed ,<https://www.scien.cx/2021/05/17/next-js-email-authentication-using-nextauth/>
VANCOUVER
flaviocopes.com | Sciencx - » Next.js Email Authentication using NextAuth. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/05/17/next-js-email-authentication-using-nextauth/
CHICAGO
" » Next.js Email Authentication using NextAuth." flaviocopes.com | Sciencx - Accessed . https://www.scien.cx/2021/05/17/next-js-email-authentication-using-nextauth/
IEEE
" » Next.js Email Authentication using NextAuth." flaviocopes.com | Sciencx [Online]. Available: https://www.scien.cx/2021/05/17/next-js-email-authentication-using-nextauth/. [Accessed: ]
rf:citation
» Next.js Email Authentication using NextAuth | flaviocopes.com | Sciencx | https://www.scien.cx/2021/05/17/next-js-email-authentication-using-nextauth/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.