Next.js中next-auth.js无法获取Session及多Provider冲突问题求助
NextAuth与Redux Provider共存及Session问题解决方案
问题1:_app.js无法获取Session
当前_app.js未通过服务端逻辑获取并传递Session,需结合Redux-wrapper的getServerSideProps和NextAuth的getSession实现:
修改_app.js,添加服务端获取Session的逻辑:
import { getSession } from "next-auth/react"; import { wrapper } from "../store"; // 替换为你的store实际路径 const MyApp = ({ Component, session, ...rest }) => { const router = useRouter(); const { store, props } = wrapper.useWrappedStore(rest); return ( <Provider store={store}> <SessionProvider session={session}> <Component {...props.pageProps} key={router.asPath} /> </SessionProvider> </Provider> ); }; export const getServerSideProps = wrapper.getServerSideProps(async (context) => { // 在服务端获取Session并传递给组件 const session = await getSession(context); return { props: { session } }; }); export default MyApp;
问题2:useSession仅返回expires,user为空对象
因使用jwt会话策略,NextAuth不会自动将authorize返回的用户信息存入Session,必须配置jwt和session回调传递用户数据:
修改[...nextauth].js,添加callbacks配置:
export const authOptions = { providers: [ CredentialsProvider({ name: "Credentials", credentials: { username: { label: "username", type: "text" }, password: { label: "password", type: "password" }, }, async authorize(credentials, req) { const { username, password } = credentials; const res = await fetch("http://localhost:8080/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ username, password }), }); const user = await res.json(); // 确保登录成功时返回有效用户,失败返回null if (user?.id) { // 根据后端返回的用户结构调整判断条件 return user; } return null; }, }), ], session: { strategy: "jwt" }, pages: { signIn: "/login" }, // 添加回调同步用户信息 callbacks: { async jwt({ token, user }) { // 登录时将用户信息存入JWT token if (user) { token.user = user; } return token; }, async session({ session, token }) { // 将JWT中的用户信息同步到Session session.user = token.user; return session; }, }, }; export default NextAuth(authOptions);
额外优化:登录处理函数增强
可在登录逻辑中添加结果判断,处理成功/失败场景:
const loginHandler = async (e) => { e.preventDefault(); const result = await signIn("credentials", { username: loginValues.username, password: loginValues.password, redirect: false, }); if (result.error) { // 处理登录错误,比如弹窗提示 console.error("登录失败:", result.error); } else { // 登录成功后跳转首页或目标页面 router.push("/"); } };
注:两个Provider的嵌套顺序无需调整,当前
Provider(Redux)包裹SessionProvider的结构合理,只要确保需要使用useSession或Redux的组件被正确包裹即可。
内容的提问来源于stack exchange,提问作者eErgun
相关产品推荐
相关产品推荐

