npm install next-auth@beta
Setup Environment
npx auth secret
Configure
// ./auth.ts
import { PrismaAdapter } from "@auth/prisma-adapter";
import NextAuth from "next-auth";
import Credentials from "next-auth/providers/credentials";
import prisma from "./prisma";
import bcrypt from "bcrypt";
export const { handlers, signIn, signOut, auth } = NextAuth({
adapter: PrismaAdapter(prisma),
secret: process.env.NEXTAUTH_SECRET,
pages: {
signIn: "/login",
},
session: {
strategy: "jwt",
maxAge: 30 * 24 * 60 * 60, // 30 days
},
providers: [
Credentials({
name: "credentials",
credentials: {
email: { label: "Email", type: "email" },
password: { label: "Password", type: "password" },
},
authorize: async (credentials: Record<string, string>) => {
try {
const { userId, password } = credentials;
const user = await prisma.user.findFirst({
where: {
OR: [{ email: userId }, { username: userId }],
},
});
if (!user) return null;
// Check if the password is correct
const isValidPassword = await bcrypt.compare(
password,
user.hashedPassword
);
if (!isValidPassword) return null;
return {
fullname: user?.fullname ?? "",
email: user?.email ?? "",
role: user?.role?.toLocaleLowerCase() ?? "user",
id: user?.id ?? "",
};
} catch (error) {
console.error("Error authorizing credentials:", error);
throw new Error("Invalid credentials");
}
},
}),
],
callbacks: {
async jwt({ token, user }) {
if (user) {
token.fullname = user.fullname;
token.role = user.role;
}
return token;
},
async session({ session, token }) {
if (token?.role) {
session.user.fullname = token.fullname as string;
session.user.role = token.role as string;
}
return session;
},
},
});
// ./app/api/auth/[...nextauth]/route.ts
import { handlers } from "@/auth" // Referring to the auth.ts we just created
export const { GET, POST } = handlers
// ./middleware.ts
export { auth as middleware } from "@/auth"
Prisma Adapter
npm install @prisma/client @auth/prisma-adapter
npm install prisma --save-dev
DATABASE_URL= "postgresql://postgres:[email protected]:5432/shopcart?schema=public"
// prima.ts
import { PrismaClient } from "@prisma/client"
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient }
export const prisma = globalForPrisma.prisma || new PrismaClient()
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma
// prisma/schema-postgres.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id String @id @default(cuid())
name String?
email String @unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
// Optional for WebAuthn support
Authenticator Authenticator[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Account {
userId String
type String
provider String
providerAccountId String
refresh_token String?
access_token String?
expires_at Int?
token_type String?
scope String?
id_token String?
session_state String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@id([provider, providerAccountId])
}
npx prisma db push
Leave a Reply