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

Next.js结合Express后端实现用户登录状态校验方案咨询

解决Next.js Middleware登录校验的三个核心问题

1. 修复Axios在Edge环境的适配错误

Next.js Middleware运行在Edge Runtime,Axios依赖的XHR/HTTP适配器不被支持,直接用原生fetch替代即可,无需额外依赖:

import { NextRequest, NextResponse } from 'next/server'

export default async function middleware(req: NextRequest) {
  const loginPageUrl = new URL('/auth/login', req.nextUrl.origin)
  const apiBaseUrl = process.env.NEXT_PUBLIC_MAIN_API

  try {
    // 用fetch替代Axios,携带请求的Cookie(JWT存在Cookie中)
    const res = await fetch(`${apiBaseUrl}/auth/whoami`, {
      credentials: 'include', // 关键:携带当前请求的Cookie
      headers: {
        'Content-Type': 'application/json',
      },
    })

    if (res.status === 401) {
      return NextResponse.redirect(loginPageUrl)
    }

    const data = await res.json()
    if (data.status !== 'success') {
      return NextResponse.redirect(loginPageUrl)
    }
  } catch (err) {
    // 处理接口调用失败的情况,比如后端宕机,默认跳登录页
    return NextResponse.redirect(loginPageUrl)
  }
}

export const config = {
  matcher: [
    '/((?!api|_next/static|_next/image|favicon.ico|auth).*)',
    '/',
  ],
}

2. 优化登录校验的标准实现

你的整体架构(Next.js前端+Express后端处理Auth)是符合常规方案的,调整几个细节让实现更规范:

  • Cookie配置:Express后端返回JWT Cookie时,务必设置HttpOnly、Secure(生产环境)、SameSite: 'lax',防止XSS攻击,同时确保跨域场景下Cookie能正常携带。
  • Middleware逻辑:优先通过HTTP状态码判断(比如401直接跳转),再处理响应体,减少不必要的JSON解析。
  • 排除路径:当前的matcher规则已经排除了登录页和静态资源,保持即可,避免循环跳转。

3. 添加缓存机制减少后端请求

每次请求都调用whoami会增加后端压力,可通过以下方式优化:

方案1:利用Edge Runtime的缓存

在fetch请求中添加缓存策略,对校验结果做短期缓存(比如5分钟),适用于登录状态不会频繁变更的场景:

const res = await fetch(`${apiBaseUrl}/auth/whoami`, {
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json',
  },
  next: { revalidate: 300 }, // Next.js 13+的缓存配置,300秒后重新校验
})

方案2:设置本地状态Cookie

在Middleware校验通过后,设置一个短期的非HttpOnly Cookie(比如is_logged_in=true),后续请求先检查这个Cookie,只有当Cookie不存在或过期时才调用后端接口:

// 先检查本地缓存Cookie
const isLoggedIn = req.cookies.get('is_logged_in')?.value === 'true'

if (!isLoggedIn) {
  // 调用后端whoami接口校验
  const res = await fetch(`${apiBaseUrl}/auth/whoami`, { credentials: 'include' })
  if (res.status !== 200) {
    return NextResponse.redirect(loginPageUrl)
  }
  // 设置缓存Cookie,有效期5分钟
  const response = NextResponse.next()
  response.cookies.set('is_logged_in', 'true', {
    maxAge: 300,
    path: '/',
    sameSite: 'lax',
  })
  return response
}

// 已登录,放行
return NextResponse.next()

注意:这个方案仅作为缓存优化,核心校验还是依赖后端的whoami接口,避免前端Cookie被篡改导致权限绕过。


内容的提问来源于stack exchange,提问作者Islam Y-

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 01:35:10