Ошибка next-auth beta, next-js 14.0.3 Error: NEXT_REDIRECT
При создание логина на сайте возникла проблема с ошибкой Error: NEXT_REDIRECT, ни как не могу понять от куда она берется и как её пофиксить, установленные пакеты: "next": "14.0.3", "next-auth": "^5.0.0-beta.4",
Суть в том что если я пытаюсь при логине, или выходе отловить ошибку try catch то получаю ошибку Error: NEXT_REDIRECT а если без неё, тогда все работает.
код.
Мой middleware я создал костюмную функцию переадресации.
//middleware.js
import NextAuth from "next-auth";
export default NextAuth({
providers: [],
pages: {
signIn: "/login",
},
callbacks: {
async authorized({ auth, request }) {
const isLoggedIn = auth?.user;
const isOnDashboard = request.nextUrl.pathname.startsWith("/dashboard");
console.log('auth:', auth, 'isLoggedIn', isLoggedIn, 'isOnDashboard', isOnDashboard)
if (isOnDashboard) {
if (isLoggedIn) return true;
return false;
} else if (isLoggedIn) {
return Response.redirect(new URL("/dashboard", request.nextUrl));
}
return true;
},
},
}).auth;
export const config = {
matcher: ['/((?!api|static|.*\\..*|_next).*)'],
}
В своём auth.js я выполняю подключение к дб, проверку если пользователь, и возвращаю его если данные верные.
//auth.js
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import { connectToDB } from "./lib/utils";
import { User } from "./lib/models";
import bcrypt from "bcrypt";
const login = async (credentials) => {
try {
connectToDB();
const user = await User.findOne({ username: credentials.username });
if (!user || !user.isAdmin) throw new Error("Wrong credentials!");
const isPasswordCorrect = await bcrypt.compare(
credentials.password,
user.password
);
if (!isPasswordCorrect) throw new Error("Wrong credentials!");
console.log('user login', user);
return user;
} catch (err) {
console.log(err);
throw new Error("Failed to login!");
}
};
export const {
handlers: { GET, POST },
signIn,
signOut,
auth
} = NextAuth({
pages: {
signIn: "/login",
},
callbacks: {
async authorized({ auth, request }) {
const isLoggedIn = auth?.user;
const isOnDashboard = request.nextUrl.pathname.startsWith("/dashboard");
console.log('auth:', auth, 'isLoggedIn', isLoggedIn, 'isOnDashboard', isOnDashboard)
if (isOnDashboard) {
if (isLoggedIn) return true;
return false;
} else if (isLoggedIn) {
return Response.redirect(new URL("/dashboard", request.nextUrl));
}
return true;
},
},,
providers: [
CredentialsProvider({
async authorize(credentials) {
try {
const user = await login(credentials);
console.log('user authorize', user);
return user;
} catch (err) {
console.log('authorize error:', err)
return null;
}
},
}),
],
callbacks: {
async jwt({ token, user }) {
if (user) {
token.username = user.username;
token.img = user.img;
}
return token;
},
async session({ session, token }) {
if (token) {
session.user.username = token.username;
session.user.img = token.img;
}
return session;
},
},
});
Теперь я пытаюсь выполнить логин через try catch
//login
<form action={async (formData) => {
"use server"
console.log('Начало 1');
try {
await signIn("credentials", formData)
} catch (error) {
console.log(error)
}
}} className={styles.form}>
<h1>Login</h1>
<input type="text" placeholder="username" name="username" />
<input type="password" placeholder="password" name="password" />
<button>Login</button>
</form>
В таком случае я получаю ошибку Error: NEXT_REDIRECT полная ошибка
Error: NEXT_REDIRECT
at getRedirectError (webpack-internal:///(rsc)/./node_modules/next/dist/client/components/redirect.js:44:19)
at redirect (webpack-internal:///(rsc)/./node_modules/next/dist/client/components/redirect.js:54:11)
at signIn (webpack-internal:///(rsc)/./node_modules/next-auth/lib/actions.js:62:89)
at async $$ACTION_1 (webpack-internal:///(rsc)/./app/ui/login/loginForm/loginForm.jsx:74:9)
at async D:\Person\Edvard\Desktop\nextadmin\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:38:489
at async tX (D:\Person\Edvard\Desktop\nextadmin\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:37:5313)
at async rl (D:\Person\Edvard\Desktop\nextadmin\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:38:23339)
at async doRender (D:\Person\Edvard\Desktop\nextadmin\node_modules\next\dist\server\base-server.js:1406:30)
at async cacheEntry.responseCache.get.routeKind (D:\Person\Edvard\Desktop\nextadmin\node_modules\next\dist\server\base-server.js:1567:28)
at async DevServer.renderToResponseWithComponentsImpl (D:\Person\Edvard\Desktop\nextadmin\node_modules\next\dist\server\base-server.js:1475:28)
at async DevServer.renderPageComponent (D:\Person\Edvard\Desktop\nextadmin\node_modules\next\dist\server\base-server.js:1852:24)
at async DevServer.renderToResponseImpl (D:\Person\Edvard\Desktop\nextadmin\node_modules\next\dist\server\base-server.js:1890:32)
at async DevServer.pipeImpl (D:\Person\Edvard\Desktop\nextadmin\node_modules\next\dist\server\base-server.js:902:25)
at async NextNodeServer.handleCatchallRenderRequest (D:\Person\Edvard\Desktop\nextadmin\node_modules\next\dist\server\next-server.js:266:17)
at async DevServer.handleRequestImpl (D:\Person\Edvard\Desktop\nextadmin\node_modules\next\dist\server\base-server.js:798:17) {
digest: 'NEXT_REDIRECT;replace;http://localhost:3000/login?callbackUrl=http%3A%2F%2Flocalhost%3A3000%2Fdashboard;false',
mutableCookies: p {
_parsed: Map(8) {
'wordpress_test_cookie' => [Object],
'wp_lang' => [Object],
'wordpress_logged_in_86a9106ae65537651a8e456835b316ab' => [Object],
'wp-settings-time-1' => [Object],
'PHPSESSID' => [Object],
'authjs.csrf-token' => [Object],
'authjs.callback-url' => [Object],
'authjs.session-token' => [Object]
},
_headers: HeadersList {
cookies: [Array],
[Symbol(headers map)]: [Map],
[Symbol(headers map sorted)]: null
}
}
}
При этом логин срабатывает! Я обновляю страницу и попадаю в уч. запись, то есть логин сам работает а редирект нет.
А если я делаю без try catch вот так
//login
<form action={async (formData) => {
"use server"
console.log('Начало 1');
await signIn("credentials", formData)
}} className={styles.form}>
<h1>Login</h1>
<input type="text" placeholder="username" name="username" />
<input type="password" placeholder="password" name="password" />
<button>Login</button>
</form>
);
То логин тоже срабатывает, и так-же переадресация тоже срабатывает.
Не знаю в чем может быть проблема, если использую try catch для отлова ошибок как в официальной документации
import { AuthError } from "next-auth"
import { signIn } from "../auth"
export default function Layout() {
return (
<form action={async (formData) => {
"use server"
try {
await signIn("credentials", formData)
} catch(error) {
if (error instanceof AuthError) // Handle auth errors
throw error // Rethrow all other errors
}
}}>
<button>Sign in</button>
</form>
)
}
То получаю ошибку, а если не использую все норм, ошибка пропадает....