Adam Richardson

Next.js Authentication with next-auth and Prisma

Adam Richardson / September 26, 2021

3 min read

Next.js Authentication with next-auth and Prisma

The first thing to do is to create a brand new Next.js application. We will create ours using the Tailwindcss example, so we don't need to configure that.

npx create-next-app --with-example tailwindcss test-auth

We will now need to install the dependencies that we need.

npm install @prisma/client @next-auth/prisma-adapter@canary next-auth
npm install prisma --save-dev

Now we will create the authentication route. Create the following new file and add these contents.

pages/api/auth/[...nextauth].js

import { PrismaAdapter } from "@next-auth/prisma-adapter";
import { PrismaClient } from "@prisma/client";
import NextAuth from "next-auth";
import Providers from "next-auth/providers";
const prisma = new PrismaClient();
export default NextAuth({
  providers: [
    Providers.Google({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
  ],
  adapter: PrismaAdapter(prisma),
});

Run the following command

npx prisma init

Let's create the Schema that next-auth needs. Notice we have chosen SQLITE as our database. Inside your prisma folder, create a file called db.db

/prisma/schema.prisma
datasource db {
  provider = "sqlite"
  url      = "file:db.db"
}

generator client {
  provider = "prisma-client-js"
}

model Account {
  id                 String    @id @default(cuid())
  userId             String
  providerType       String
  providerId         String
  providerAccountId  String
  refreshToken       String?
  accessToken        String?
  accessTokenExpires DateTime?
  createdAt          DateTime  @default(now())
  updatedAt          DateTime  @updatedAt
  user               User      @relation(fields: [userId], references: [id])
  @@unique([providerId, providerAccountId])
  }

model Session {
  id           String   @id @default(cuid())
  userId       String
  expires      DateTime
  sessionToken String   @unique
  accessToken  String   @unique
  createdAt    DateTime @default(now())
  updatedAt    DateTime @updatedAt
  user         User     @relation(fields: [userId], references: [id])
  }

model User {
  id            String    @id @default(cuid())
  name          String?
  email         String?   @unique
  emailVerified DateTime?
  image         String?
  createdAt     DateTime  @default(now())
  updatedAt     DateTime  @updatedAt
  accounts      Account[]
  sessions      Session[]
  }

model VerificationRequest {
  id         String   @id @default(cuid())
  identifier String
  token      String   @unique
  expires    DateTime
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt
  @@unique([identifier, token])
  }

Now our authentication is almost good to go. We need to run our database migration.

npx prisma migrate dev --name "Add authentication"

We can now start using our authentication on the front end of our website. Here is the example code from Next-auth documentation.

pages/index.js

import { signIn, signOut, useSession } from "next-auth/client"

const [session, loading] = useSession()

  {!session && (
    <>
      {" "}
      Not signed in <br /> <button onClick={() => signIn()}>Sign in</button>{" "}
    </>
  )}{" "}
  {session && (
    <>
      {" "}
      Signed in as {session.user.email} <br />{" "}
      <button onClick={() => signOut()}>Sign out</button>{" "}
    </>
  )}

pages/_app.js
import { Provider } from "next-auth/client"

export default function App({ Component, pageProps }) {
  return (
    <Provider session={pageProps.session}>
          <Component {...pageProps} />
    </Provider>  )}

Authentication in an API route?

pages/api/createprofile
import { getSession } from "next-auth/client";

export default async function (req, res) {
const session = await getSession({ req });

if (!session) {
  return res.status(401);
}

// Do authenticated stuff here...
}

© 2021 Adam Richardson. All rights reserved.