How to Add Passwordless Email Authentication (Magic Links) with NextAuth


I wanted to configure passwordless email authentication in my Next.js application. Specifically, I wanted a user to be able to submit their email, which will trigger a magic link to be sent to the user’s email, allowing them to log in.

I didn’t want to worry about passwords but also needed to accomodate those who could not sign in with the available OAuth providers.

I had previously set up a Postgres database in my Next.js application using a Prisma database adapter. I was already persisting users who had logged in with OAuth, and I also wanted to give users the option to use passwordless authentication.

Disclaimer: in this guide, I’m assuming you have a database set up. You can follow my previous articles to do this if you haven’t.

Passwordless Email Authentication

In order to provide passwordless email authentication with magic links, we’ll need access to an SMTP (Simple Mail Transfer Protocol) server. The purpose of these servers are simply to send, receive, or relay mail between multiple clients.

For smaller projects, I would recommend using SendGrid. It is what I used for my first few projects.

Obtain SendGrid API Key

Create an account. The first step is to create a SendGrid account.

Create a sender identity. Once we’ve registered, we’ll need to create a sender identity. This is where we specify the email address(es) that will send/receive emails to/from users. This should be available from the SendGrid Sender Auth Settings.

We’ll have to fill out a few fields, most notably the From and To email addresses.

  • From Email Address: the email address which will send all emails
  • Reply To: the email address which will receive all replies (could be the same)

Afterwards, we should get an email at the From Email Address email address to verify this information.

Create an API Key. Next, we’ll want to obtain our SMTP configuration details. We’ll follow the integration guide.

Let’s head to Email API > Integration Guide > SMTP Relay > Choose.

Type in any API Key name and select Create Key.

This should populate the Password field in the table. (We could also do this manually in the API Keys page).

Property Value
Server smtp.sendgrid.net
Ports 25, 587 (for unencrypted/TLS connections)
465 (for SSL connections)
Username apikey
Password SG.random_string.longer_random_string

Configure NextAuth to use SendGrid

Next, we’ll want to add these values as environment variables to our .env.

# .env
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USER=apikey
SMTP_PASSWORD=SG.random_string.longer_random_string
SMTP_FROM=SendGrid_From_Email_Address@some_email.com

Now, we’ll use these variables in our pages/api/auth/[...nextauth].js file to configure our email provider.

We’ll add EmailProvider({}) as an element of providers.

The code snippets here require NextAuth.js v4. Check out how to upgrade to version 4.

// pages/api/auth/[...nextauth].js
import EmailProvider from `next-auth/providers/email`;
export default NextAuth({
  providers: [
    EmailProvider({
      server: {
        host: process.env.SMTP_HOST,
        port: Number(process.env.SMTP_PORT),
        auth: {
          user: process.env.SMTP_USER,
          pass: process.env.SMTP_PASSWORD
        },
      },
      from: process.env.SMTP_FROM
    }),
    ...
  ],
});

A database is required for this passwordless authentication, so we should have either an adapter or database field populated in our next-auth configuration.

We can now send magic links to authenticate our users!