You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextAuth v5登录后Session未更新及中间件重定向失效求助

NextAuth v5 问题求助

我是NextAuth v5新手,目前遇到两个问题:

  1. 用户登录后Session数据不会自动更新,必须手动刷新页面(目前用setTimeout强制刷新);
  2. 尝试通过Middleware将已登录用户从/sign-in和/sign-up路由重定向,但未按预期生效。

已查阅官方文档、咨询AI助手并观看教程,仍无法解决。


相关代码

auth.js

const authOptions = {
  providers: [
    Credentials({
      name: "credentials",
      credentials: {
        
      },
      async authorize(credentials) {
        if (credentials === null) return null;
        const { username, password } = credentials;

        try {
          await connectDB();
          const user= await User.findOne({username});
          
          if (!user) {
            throw new Error("User not found");
          }
          const passwordMatch= await bcrypt.compare(password, user.password);
          if (!passwordMatch) {
            throw new Error("Email or Password is not correct");
          }

          return { id: user._id, fullname: user.fullname, username: user.username, profile: user.profilepic };
        } catch (error) {
          console.error(error);
          return null;
        }
      },
    }),
  ],
  secret: process.env.AUTH_SECRET,
  pages: {
    signIn: "/sign-in",
  },
  session:{
    strategy: "jwt",
  },
  callbacks: {
    async jwt({ token, user }) {
      if (user) {
        token.id = user.id;
        token.fullname = user.fullname;
        token.username = user.username;
        token.profile = user.profile;
      }
      return token;
    },
    async session({ session, token }) {
      session.user.id = token.id;
      session.user.fullname = token.fullname;
      session.user.username = token.username;
      session.user.profile = token.profile;
      return session;
    },
    
  },
 
};

export const { handlers, auth, signIn, signOut,update } = NextAuth(authOptions);

helper.js

'use server'
import { signIn,signOut } from '@/auth'

export async function doCredentialLogin(inputs) {
  try {
    const res= await signIn('credentials', {
      redirect: false,
      username: inputs.username,
      password: inputs.password
    });
    return res;
  } catch (error) {
    console.log(error)
  }
}

export async function doLogout() {
  await signOut({ redirectTo: "/sign-in" });

}

useSignup.jsx

const useSignUp = () => {
    const [loading,setLoading]=useState(false)
    const router = useRouter()

    const signup=async({fullname,username,password,confirmPassword})=>{
        const sucess=handleInputErrors({fullname,username,password,confirmPassword});
        if(!sucess) return;
        setLoading(true)
        try {
            const res=await fetch('/api/sign-up',{
                method:'POST',
                headers:{
                    'Content-Type':'application/json'
                },
                body:JSON.stringify({fullname,username,password,confirmPassword})
            })
            if(res.status===201)
                {
                const signInRes=await doCredentialLogin({username,password})
                if(signInRes.error) throw new Error("An unexpected error occurred")
                toast.success("Account created successfully!")
                router.push('/')
                setTimeout(() => {
                    window.location.reload(); 
                  }, 600);  
            
                }
            else{
                const data=await res.json()
                throw new Error(data.error)
            }
            
        } catch (error) {
            toast.error(error.message)       
        }
        finally{
            setLoading(false)
        }
    }
    return {signup,loading}
}

export default useSignUp;

/sign-in 页面代码

const { update } = useSession();

  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);
  
    try {
      const res = await doCredentialLogin(inputs);
  
      if (res.error) {
        console.error(res.error);
        toast.error("Invalid credentials");
      } else {
        await update();
        router.push('/');  // Navigate to the home page
      setTimeout(() => {
        window.location.reload();  // Force page reload
      }, 500);  // Adjust the timeout as needed

      }
    } catch (error) {
      console.error('login', error);
      toast.error("An unexpected error occurred");
    } finally {
      setLoading(false);
    }
  };

middleware.ts

import { auth } from "@/auth"; 
import { NextResponse } from "next/server";

export default auth((req) => {
  if (!req.auth) {
    const url = req.url.replace(req.nextUrl.pathname, "/");
    return NextResponse.redirect(url);
  }
});

export const config = {
  matcher: ["/sign-in", "/sign-up"],
};

解决方案

问题1:Session登录后不自动更新

你当前的问题源于使用redirect: false时,NextAuth不会自动触发Session同步。可以两种方式解决:

  1. 推荐方案:使用默认跳转逻辑
    修改doCredentialLogin,移除redirect: false,让NextAuth自动处理登录后的Session更新和跳转:

    export async function doCredentialLogin(inputs) {
      try {
        await signIn('credentials', {
          username: inputs.username,
          password: inputs.password,
          redirectTo: '/'
        });
      } catch (error) {
        console.log(error)
      }
    }
    

    同时简化sign-in页面的handleSubmit,无需手动跳转和刷新:

    const handleSubmit = async (e) => {
      e.preventDefault();
      setLoading(true);
    
      try {
        await doCredentialLogin(inputs);
      } catch (error) {
        console.error('login', error);
        toast.error("An unexpected error occurred");
      } finally {
        setLoading(false);
      }
    };
    
  2. 保留redirect: false的方案
    用Next.js的router.refresh()代替全页面刷新,配合update()同步Session:

    else {
      await update();
      router.push('/');
      router.refresh();
    }
    

问题2:Middleware重定向失效

你的Middleware逻辑写反了,当前是拦截未登录用户,需要改为拦截已登录用户:

import { auth } from "@/auth"; 
import { NextResponse } from "next/server";

export default auth((req) => {
  if (req.auth && (req.nextUrl.pathname === '/sign-in' || req.nextUrl.pathname === '/sign-up')) {
    return NextResponse.redirect(new URL('/', req.url));
  }
});

export const config = {
  matcher: ["/sign-in", "/sign-up"],
};

确认Middleware文件放在项目根目录,且NextAuth v5的auth函数能正确获取会话即可。


内容的提问来源于stack exchange,提问作者Gia Nguyen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 07:19:55