import { type NextRequest, NextResponse } from "next/server"; import { getToken } from "next-auth/jwt"; export async function middleware(request: NextRequest) { const { pathname } = request.nextUrl; // 允许访问 ping 端点 if (pathname.startsWith("/ping")) { return NextResponse.next(); } // 允许访问认证相关 API if (pathname.startsWith("/api/auth")) { return NextResponse.next(); } // 允许访问公开的网站设置 API(登录页面需要) if (pathname === "/api/site-settings") { return NextResponse.next(); } // 允许访问钉钉回调页面(public 文件夹中的文件) if (pathname === "/dingtalk-callback.html") { return NextResponse.next(); } // 检测是否为 HTTPS(通过 AUTH_URL 或请求协议判断) const isSecure = process.env.AUTH_URL?.startsWith("https://") || request.nextUrl.protocol === "https:"; const token = await getToken({ req: request, secret: process.env.AUTH_SECRET, secureCookie: isSecure, }); const externalBase = process.env.AUTH_URL ?? `${request.nextUrl.protocol}//${request.headers.get("host") ?? request.nextUrl.host}`; // 未登录用户只能访问 /login 和 /register if (!token && !["/login", "/register"].includes(pathname)) { const loginUrl = new URL("/login", externalBase); // 保存当前路径作为回调 URL loginUrl.searchParams.set("callbackUrl", pathname); return NextResponse.redirect(loginUrl); } // 已登录用户访问 /login 或 /register 时重定向到首页 if (token && ["/login", "/register"].includes(pathname)) { return NextResponse.redirect(new URL("/", externalBase)); } return NextResponse.next(); } export const config = { matcher: [ /* * 匹配所有请求路径,除了: * - api/auth (NextAuth.js) * - _next/static (静态文件) * - _next/image (图片优化文件) * - favicon.ico (favicon文件) * - public 文件夹中的文件 */ "/((?!api/auth|_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)", ], };