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

如何将next-intl中间件与Next.js 15现有认证中间件整合?

解决Next.js 15 App Router中next-intl与认证中间件结合的问题

核心问题分析

现有认证中间件直接判断pathname是否为/einloggen,但next-intl会为路由添加locale前缀(比如/de/einloggen或/en/login),导致认证逻辑无法匹配;同时两个中间件的执行顺序和路由解析逻辑需要整合到同一个middleware中,不能分开运行。

具体实现步骤

1. 合并中间件逻辑

将next-intl的路由处理逻辑和认证逻辑整合到同一个src/middleware.ts文件中。

2. 完整整合代码

import { NextRequest, NextResponse } from "next/server";
import { getSession } from "@/lib/auth/iron-session";
import createMiddleware from "next-intl/middleware";

// 初始化next-intl中间件,配置支持的语言和默认语言
const intlMiddleware = createMiddleware({
  locales: ["de", "en"], // 根据实际业务调整语言列表
  defaultLocale: "de"
});

export async function middleware(request: NextRequest) {
  // 先执行next-intl的路由本地化处理
  const intlResponse = intlMiddleware(request);

  // 提取不带locale前缀的路径,比如从/de/einloggen得到/einloggen
  const localePrefixPattern = /^\/([a-z]{2})\//;
  const cleanPathname = request.nextUrl.pathname.replace(localePrefixPattern, "/");

  // 执行原有认证逻辑
  const session = await getSession();
  const isLoggedIn = session.isLoggedIn;

  // 调整认证判断逻辑,适配本地化路径
  if (!isLoggedIn && cleanPathname !== "/einloggen") {
    // 重定向到对应语言的登录页
    const loginUrl = new URL(`/${request.nextUrl.locale || "de"}/einloggen`, request.url);
    return NextResponse.redirect(loginUrl);
  }
  if (isLoggedIn && cleanPathname === "/einloggen") {
    // 重定向到对应语言的首页
    const homeUrl = new URL(`/${request.nextUrl.locale || "de"}`, request.url);
    return NextResponse.redirect(homeUrl);
  }

  // 认证逻辑无重定向时,返回next-intl处理后的响应
  return intlResponse;
}

export const config = {
  // 匹配所有需处理路由,排除next内部资源和静态文件
  matcher: ["/((?!_next|favicon.ico|assets).*)"]
};

3. 关键调整说明

  • 整合中间件执行顺序:先让next-intl完成路由本地化解析,再基于清理后的路径执行认证判断,避免locale前缀干扰逻辑。
  • 路径清理:通过正则移除locale前缀,让原有认证逻辑无需修改即可适配多语言路由。
  • 本地化重定向:重定向时自动带上当前语言前缀,避免触发next-intl的二次路由修正。
  • 兼容matcher配置:保持原有排除规则,确保静态资源和next内部路径不被中间件处理。

4. 多语言登录页适配(可选)

如果不同语言对应不同登录页路径(比如德语/einloggen、英语/login),可修改认证逻辑如下:

// 定义各语言对应的登录页路径
const loginPaths = {
  de: "/einloggen",
  en: "/login"
};
const currentLoginPath = loginPaths[request.nextUrl.locale as keyof typeof loginPaths] || "/einloggen";

// 替换原有判断逻辑中的"/einloggen"为currentLoginPath
if (!isLoggedIn && cleanPathname !== currentLoginPath) {
  const loginUrl = new URL(`/${request.nextUrl.locale || "de"}${currentLoginPath}`, request.url);
  return NextResponse.redirect(loginUrl);
}
if (isLoggedIn && cleanPathname === currentLoginPath) {
  const homeUrl = new URL(`/${request.nextUrl.locale || "de"}`, request.url);
  return NextResponse.redirect(homeUrl);
}

内容的提问来源于stack exchange,提问作者Assad Rajab

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:50:10