- Published on
Auth.js: Setting Up in Next.js
- Authors
- Name
- Shelton Ma
1. Auth.js Setup
1. Installing Auth.js
pnpm add next-auth@beta
2. Generate a Secret Key
npx auth secret
3. Configure
Create NextAuth
// src/auth.ts import NextAuth from "next-auth" export const { handlers, signIn, signOut, auth } = NextAuth({ providers: [], })
Add a Route Handler
// src/app/api/auth/[...nextauth]/route.ts import { handlers } from "@/auth" // Referring to the auth.ts we just created export const { GET, POST } = handlers
Add Middleware
// src/middleware.ts export { auth as middleware } from "@/auth"
2. Database Adapters (connect Auth.js to your database)
Install drizzle-adapter
pnpm add drizzle-orm @auth/drizzle-adapter pnpm add drizzle-kit --save-dev
Schemas
// src/db/schema.ts import { boolean, timestamp, pgTable, text, primaryKey, integer, } from "drizzle-orm/pg-core" import postgres from "postgres" import { drizzle } from "drizzle-orm/postgres-js" import type { AdapterAccountType } from "next-auth/adapters" const connectionString = "postgres://postgres:postgres@localhost:5432/drizzle" const pool = postgres(connectionString, { max: 1 }) export const db = drizzle(pool) export const users = pgTable("user", { id: text("id") .primaryKey() .$defaultFn(() => crypto.randomUUID()), name: text("name"), email: text("email").unique(), emailVerified: timestamp("emailVerified", { mode: "date" }), image: text("image"), }) export const accounts = pgTable( "account", { userId: text("userId") .notNull() .references(() => users.id, { onDelete: "cascade" }), type: text("type").$type<AdapterAccountType>().notNull(), provider: text("provider").notNull(), providerAccountId: text("providerAccountId").notNull(), refresh_token: text("refresh_token"), access_token: text("access_token"), expires_at: integer("expires_at"), token_type: text("token_type"), scope: text("scope"), id_token: text("id_token"), session_state: text("session_state"), }, (account) => [ { compoundKey: primaryKey({ columns: [account.provider, account.providerAccountId], }), }, ] ) export const sessions = pgTable("session", { sessionToken: text("sessionToken").primaryKey(), userId: text("userId") .notNull() .references(() => users.id, { onDelete: "cascade" }), expires: timestamp("expires", { mode: "date" }).notNull(), }) export const verificationTokens = pgTable( "verificationToken", { identifier: text("identifier").notNull(), token: text("token").notNull(), expires: timestamp("expires", { mode: "date" }).notNull(), }, (verificationToken) => [ { compositePk: primaryKey({ columns: [verificationToken.identifier, verificationToken.token], }), }, ] ) export const authenticators = pgTable( "authenticator", { credentialID: text("credentialID").notNull().unique(), userId: text("userId") .notNull() .references(() => users.id, { onDelete: "cascade" }), providerAccountId: text("providerAccountId").notNull(), credentialPublicKey: text("credentialPublicKey").notNull(), counter: integer("counter").notNull(), credentialDeviceType: text("credentialDeviceType").notNull(), credentialBackedUp: boolean("credentialBackedUp").notNull(), transports: text("transports"), }, (authenticator) => [ { compositePK: primaryKey({ columns: [authenticator.userId, authenticator.credentialID], }), }, ] )
Add DrizzleAdapter
// src/auth.ts import NextAuth from "next-auth" import { DrizzleAdapter } from "@auth/drizzle-adapter" import { db } from "./db/drizzle"; export const { handlers, auth, signIn, signOut } = NextAuth({ adapter: DrizzleAdapter(db), providers: [], })