URL传外部accessToken时如何绕过NextAuth认证
问题根因
- 执行时序完全错误:Next.js Middleware 运行在请求路由匹配阶段,执行优先级远高于_app.tsx等页面代码。你在_app.tsx里通过
document.cookie写入Cookie的操作,是在Middleware校验完成、页面已经加载到浏览器环境后才触发的,Middleware运行时根本拿不到后续才写入的Cookie,这是getCookie返回null的核心原因。 - 代码存在笔误:你贴出的_app.tsx代码片段中,判断条件和实际写入的Cookie键是
storeNumber,根本没有写入accessToken对应的Cookie值,就算时序正确也无法读取到目标值。 - Cookie读取方式不符合Middleware运行环境要求:基于Edge Runtime的Middleware不能直接调用通用浏览器侧/Node侧的
getCookie方法读取Cookie,必须从当前请求对象的实例上解析Cookie内容。
正确实现方案
不要绕路在前端页面写Cookie,直接在Middleware层完成参数提取、Cookie写入、权限校验的全逻辑,这是最符合Next.js请求处理链路的方案。
修改_middleware.ts逻辑
直接在Middleware入口解析请求URL上的accessToken参数,存在的话自动种Cookie并放行,不存在就走原有NextAuth认证流程:
import { withAuth } from "next-auth/middleware"; import { NextResponse } from "next/server"; export default withAuth( function middleware(req) { // 直接从当前请求URL提取accessToken参数 const accessToken = req.nextUrl.searchParams.get("accessToken"); if (accessToken) { const response = NextResponse.next(); // 写入Cookie,配置根据实际需求调整 response.cookies.set("accessToken", accessToken, { path: "/", maxAge: 7200, // 临时令牌有效期建议设短 sameSite: "lax", }); return response; } return NextResponse.next(); }, { pages: { signIn: "/auth/signin", }, callbacks: { authorized: ({ req, token }) => { // 从请求对象上读取Cookie中的accessToken const cookieAccessToken = req.cookies.get("accessToken")?.value; // 存在URL传入的令牌则直接放行,否则走原有NextAuth的token校验 return !!cookieAccessToken || !!token; }, }, } ); // 配置需要走认证校验的路由范围,按实际业务调整 export const config = { matcher: ["/((?!api/auth|auth/signin|_next/static|favicon.ico).*)"], };
清理_app.tsx冗余代码
之前在_app.tsx里写的从callbackUrl提取accessToken、写入Cookie的逻辑可以全部删除,这段代码执行时机太晚,完全不生效还会造成逻辑冗余。
注意事项
- URL明文传accessToken存在安全风险,令牌会泄露在浏览器历史记录、服务器访问日志、请求Referer头中,仅建议在内部项目临时场景使用,不要在公网生产环境长期保留该逻辑。
- 该方案下,首次带accessToken访问时Middleware会自动把令牌写入Cookie,后续同站点下的页面跳转、API请求都会自动带上该Cookie,不需要每次URL都拼接参数,直到Cookie过期。
- 如果需要在前端组件、API路由中使用该accessToken,直接从Cookie中读取即可,不需要额外做存储同步。
内容的提问来源于stack exchange,提问作者RebootGG
相关产品推荐
相关产品推荐

