Hi I am trying to implement a login with next-auth in next 13 has appDir: true
and the version of next is 13.3.0 but I checked the documentation but the truth is I don't understand, I am doing it with typescript but there is almost no documentation and I don't know if I am doing it right.
app/api/auth/[...nextauth]/route.ts
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
const handler = NextAuth({
providers: [
CredentialsProvider({
name: "Credentials",
credentials: {
username: { label: "Username", type: "text" },
password: { label: "Password", type: "password" },
},
async authorize(credentials, req) {
const { username, password } = credentials as { username: string; password: string };
const res = await fetch("http://localhost:3000/api/auth/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ username, password }),
});
const user = await res.json();
if (res.ok) {
return user;
} else {
return null;
}
},
}),
],
session: {
strategy: "jwt"
},
});
export { handler as GET, handler as POST };
layout.tsx
'use client'
import './globals.css'
import { SessionProvider } from "next-auth/react"
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<SessionProvider>
{children}
</SessionProvider>
</body>
</html>
)
}
when I add the <SessionProvider>{children}</SessionProvider>
I get the following error and it does not load the pages.
app/api/auth/[... nextauth]/route.ts
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
interface User {
id: number;
name: string;
email: string;
password: string;
role: string;
created_at: string;
updated_at?: any;
iat: number;
exp: number;
jti: string;
}
const handler = NextAuth({
session: {
strategy: "jwt",
},
providers: [
CredentialsProvider({
name: "Credentials",
credentials: {
email: { label: "Email", type: "text", placeholder: "jsmith" },
password: { label: "Password", type: "password" },
},
async authorize(credentials) {
const { email, password } = credentials as {
email: string;
password: string;
};
const res = await fetch("http://127.0.0.1:8000/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ email, password }),
});
// tipar peticion de user
const user = await res.json();
if (res.ok && user) {
// mostrar el encabezado de autorización en la consola
return user;
} else {
return null;
}
},
}),
],
callbacks: {
jwt: async ({ token, user }) => {
if (user) token = user as unknown as { [key: string]: any };
console.log(token);
return token;
},
session: async ({ session, token }) => {
session.user = { ...token }
return session;
},
},
secret: "supersecret",
pages: {
signIn: "/login",
},
});
export { handler as GET, handler as POST };
app/Providers.tsx
'use client'
import React, { ReactNode } from 'react';
import { SessionProvider } from "next-auth/react"
interface Props {
children: ReactNode
}
function Providers({ children }: Props) {
return <SessionProvider>{children}</SessionProvider>
}
export default Providers;
layout.tsx
import { ReactNode } from 'react'
import './globals.css'
import Provider from './Providers'
interface Props {
children: ReactNode
}
export default function RootLayout({ children }: Props) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Generated by create next app" />
<meta name="author" content="Vercel" />
<link rel="stylesheet" href="https://cdn.lineicons.com/4.0/lineicons.css" />
</head>
<body>
<Provider>{children}</Provider>
</body>
</html>
)
}
and when sending the credentials, the same credentials and data are sent.