Next.js App Router登录提交后router.push失效及回退异常求助
Next.js App Router 登录跳转与Middleware校验异常问题
问题背景
我基于Next.js App Router开发项目,已通过Middleware实现access token的校验逻辑:
- 用户无token时,访问根路径(/)及登录相关页面以外的页面,会自动携带
returnURL参数跳转到登录页,登录完成后应跳转回原页面,但该逻辑未正常工作。 - 登录流程采用
react-hook-form结合tanstack-query的useMutation实现。
现有代码
登录组件核心代码
const returnURL = useSearchParams().get('returnURL') || '/'; // 提交处理函数 const onSubmit: SubmitHandler<FieldValues> = () => { postSigninMutate( { username: payload.username, password: payload.password }, { onSuccess: async (res) => { const { response } = res; const authorizationToken = response.headers.get('authorization-token'); const expiresAt = response.headers.get('authorization-token-expired-at'); const refreshToken = response.headers.get('refresh-token'); if (authorizationToken && expiresAt && refreshToken) { Cookies.set('authorization-token', authorizationToken, { secure: true }); Cookies.set('expires-at', expiresAt); Cookies.set('refresh-token', refreshToken, { secure: true }); } router.push(returnURL); }, onError: (err) => alert(err) } ); }; <form onSubmit={handleSubmit(onSubmit)} className="flex-col-start m-0 w-80 gap-6 pt-10"> ...
Middleware代码(middleware.ts)
import { NextRequest, NextResponse } from 'next/server'; export function middleware(request: NextRequest) { const url = request.nextUrl.pathname; const accessToken = request.cookies.get('authorization-token'); console.log(accessToken ? 'yes' : 'no'); console.log(url); if (url === '/') { const response = NextResponse.next(); response.headers.set('X-Skip-Icons', 'true'); return response; } if ( accessToken && (url === '/signup' || url === '/login' || url === '/kakaoLogin' || url === '/find-password-email' || url === '/find-password-question' || url === '/find-password-newpassword') ) { if (request.nextUrl.searchParams.has('returnURL')) { return NextResponse.redirect(new URL(request.nextUrl.searchParams.get('returnURL') || '/', request.url)); } console.log('here'); return NextResponse.redirect(new URL('/', request.url)); } if ( !accessToken && url !== '/signup' && url !== '/login' && url !== '/kakaoLogin' && url !== '/find-password-email' && url !== '/find-password-question' && url !== '/find-password-newpassword' ) { const redirectURL = new URL('/login', request.url); const returnURL = request.nextUrl.pathname + request.nextUrl.search; redirectURL.searchParams.set('returnURL', returnURL); const response = NextResponse.redirect(redirectURL); return response; } return NextResponse.next(); } export const config = { matcher: ['/((?!api|_next/static|_next/image|favicon.ico|icons/favicon.ico|icon).*)'] };
临时解决方案与疑问
我怀疑问题源于页面缓存、客户端与服务器的cookie更新不同步。尝试在登录成功后调用router.refresh(),此时Middleware会触发、页面也会更新,但地址栏URL没有变化。之后我添加了setTimeout延迟执行router.push(returnURL),虽然能实现跳转,但不确定这是不是正确的解决方案:
router.refresh(); setTimeout(() => { router.push(returnURL); }, 1000);
额外问题
登录成功后,按浏览器返回键仍能回到登录页,不符合预期。
内容的提问来源于stack exchange,提问作者ayoung
相关产品推荐
相关产品推荐

