中间件在下次验证后登录得到无限循环



使用中间件保护所有路由,签到后得到无限循环

这是我的中间件:

export default withAuth({
callbacks: {
authorized: async ({ req, token }) => {
const pathname = req.nextUrl.pathname;
if (
pathname.startsWith("/_next") ||
pathname === "/favicon.ico" ||
pathname === "/__ENV.js"
) {
return true;
}
if (token) {
return true;
}
return false;
},
},
secret: "test",
pages: {
signIn: "/auth/signin",
},
});

这是我的签到页面:

import { signIn, useSession } from "next-auth/react";
import { useEffect } from "react";
import { useRouter } from "next/router";
export default function Signin() {
const router = useRouter();
const { data: session, status } = useSession();
useEffect(() => {
if (session == null || session?.error === "RefreshAccessTokenError") {
signIn("keycloak");
} else if (status === "authenticated") {
router.push("/");
}
}, [session, router, status]);
return <div></div>;
}

这是我的url看起来像我登录后-http://localhost:3000/auth/signin?callbackUrl=%2F

缺少什么?

据我所知,使用withAuth中间件保护路由只支持jwt策略。如果你使用的是数据库策略这不是一个选项

看到这个

首先,中间件对async / await语法有一个困难的事情,尝试使用旧的Promise看看它是否有帮助。

如果你还在使用以前的12.2(旧中间件)nextjs,我建议先迁移nextjs和next-auth。如果您无法负担迁移费用,最好排除withAuth之前的路径,而不是之后的路径。

const EXCLUDED_PATHS = [/^/_next/, /^/favicon.ico$/, /^/__ENV.js$/]
const middleware: NextMiddleware = (req, res) => {
const { pathname } = req.nextUrl
// Exclude some paths
if (excludePaths.some((regexp) => regexp.test(pathname))) {
return NextResponse.next()
}
return withAuth(req, {
/*auth options*/
})
}
export default middleware

有同样的问题。这为我修复了它:将此功能添加到Signin:

Signin.getInitialProps = async (context) => {
const providers = await getProviders();
return {
providers,
callbackUrl: context.query.callbackUrl
};
};

上面的函数发送一个callbackUrl给Signin函数。在你的Signin函数中,不是调用signIn("keycloak");,而是调用signIn("keycloak",{ callbackUrl: callbackUrl })。确保您的登录函数接受这些参数。总而言之,你的登录函数应该是:

import { signIn, useSession } from "next-auth/react";
import { useEffect } from "react";
import { useRouter } from "next/router";
export default function Signin({providers,callbackUrl}) {
const router = useRouter();
const { data: session, status } = useSession();
useEffect(() => {
if (session == null || session?.error === "RefreshAccessTokenError") {
signIn("keycloak",{ callbackUrl: callbackUrl });
} else if (status === "authenticated") {
router.push("/");
}
}, [session, router, status]);
return <div></div>;
}
Signin.getInitialProps = async (context) => {
const providers = await getProviders();
return {
providers,
callbackUrl: context.query.callbackUrl
};
};

在您的例子中,您可能不希望从getInitialProps函数返回提供商。您可以相应地修改它。希望这对你有帮助!

最新更新