As I delve into the realm of Next.js and utilize NextAuth for authentication in my application, I've discovered that Next-auth handles the session and token management. My objective is to extract the email of the authenticated user from the data stored in the user's session. Here are my configuration files, utilizing the credential provider method. "next": "15.0.0-canary.56" "next-auth": "5.0.0-beta.20".
import type { NextAuthConfig } from 'next-auth';
export const authConfig = {
pages: {
signIn: '/login',
},
callbacks: {
authorized({ auth, request: { nextUrl } }) {
const isLoggedIn = !!auth?.user;
const isOnDashboard = nextUrl.pathname.startsWith('/dashboard');
if (isOnDashboard) {
if (isLoggedIn) return true;
return false; // Redirect unauthenticated users to login page
} else if (isLoggedIn) {
return Response.redirect(new URL('/dashboard', nextUrl));
}
return true;
},
},
providers: [], // Add providers with an empty array for now
} satisfies NextAuthConfig;
import NextAuth from 'next-auth';
import { authConfig } from './auth.config';
import Credentials from 'next-auth/providers/credentials';
import z from 'zod'
import type { User } from '@/app/lib/definitions';
import bcrypt from 'bcrypt';
import { sql } from '@vercel/postgres';
import NextAuthOptions from 'next-auth'
async function getUser(email: string): Promise<User | undefined> {
try {
const user = await sql<User>`SELECT * FROM users WHERE email=${email}`;
return user.rows[0];
} catch (error) {
console.error('Failed to fetch user:', error);
throw new Error('Failed to fetch user.');
}
}
export const { auth, signIn, signOut } = NextAuth({
...authConfig,
providers: [
Credentials({
async authorize(credentials) {
const parsedCredentials = z
.object({ email: z.string().email(), password: z.string().min(6) })
.safeParse(credentials);
if (parsedCredentials.success) {
const { email, password } = parsedCredentials.data;
const user = await getUser(email);
if (!user) return null;
const passwordsMatch = await bcrypt.compare(password, user.password);
if (passwordsMatch) return user;
}
console.log('Invalid credentials');
return null;
},
}),
],
session: {
strategy :'jwt',
},
pages: {
signIn: '/auth/signin',
},
});
This snippet displays how I am attempting to obtain session details:
//app/api/auth/session
import { getServerSession } from 'next-auth/next';
import { authConfig } from '@/auth.config';
import { NextResponse } from 'next/server';
export async function GET() {
const session = await getServerSession(authConfig);
if (session) {
return NextResponse.json(session);
} else {
return NextResponse.json({ error: 'No active session' }, { status: 401 });
}
}
My endeavor to utilize the SessionProvider in the RootLayout component was fruitless:
import '@/app/ui/global.css';
import { SessionProvider } from 'next-auth/react';
export default function RootLayout({
children,
session,
}: {
children: React.ReactNode;
session: any;
}) {
return (
<html lang="en">
<body>
<SessionProvider session={session}>
{children}
</SessionProvider>
</body>
</html>
);
}
This particular component is where I hoped to gather information:
import RootLayout from '@/app/layout';
import { getSession } from 'next-auth/react';
export default async function Page() {
const session = await getSession();
return (
<RootLayout session={session}>
<div>The user_email is {session?.user?.email}</div>
</RootLayout>
);
}