import { NextResponse } from "next/server" import type { NextRequest } from "next/server" // 需要认证的路由 const protectedRoutes = [ "/profile", "/profile/account", "/profile/edit", "/create", "/settings", "/login/fields", "/chat", "/contact", "/vip", "/wallet", "/wallet/transactions", "/crushcoin", ] // 已登录用户不应该访问的路由 const authRoutes = [ "/login", ] const DEVICE_ID_COOKIE_NAME = 'sd' // 生成设备ID function generateDeviceId(userAgent?: string): string { const timestamp = Date.now().toString(36) const randomStr = Math.random().toString(36).substring(2, 15) const browserInfo = userAgent ? userAgent.replace(/\s/g, '').substring(0, 10) : 'server' return `did_${timestamp}_${randomStr}_${browserInfo}`.toLowerCase() } export default function middleware(request: NextRequest) { const { pathname } = request.nextUrl // console.log('🔄 [MIDDLEWARE] 开始处理路径:', pathname) // console.log('🔄 [MIDDLEWARE] 请求方法:', request.method) // console.log('🔄 [MIDDLEWARE] User-Agent:', request.headers.get('user-agent')?.substring(0, 50)) // console.log('🔄 [MIDDLEWARE] 请求头:', Object.fromEntries(request.headers.entries())) // 获取现有设备ID let deviceId = request.cookies.get(DEVICE_ID_COOKIE_NAME)?.value let needSetCookie = false if (!deviceId) { // 生成新的设备ID const userAgent = request.headers.get('user-agent') || undefined deviceId = generateDeviceId(userAgent) needSetCookie = true // console.log('🆕 [MIDDLEWARE] 生成新设备ID:', deviceId) } else { console.log('✅ [MIDDLEWARE] 获取现有设备ID:', deviceId) } // 认证逻辑 const token = request.cookies.get("st")?.value const isAuthenticated = !!token const isProtectedRoute = protectedRoutes.some(route => pathname.startsWith(route)) const isAuthRoute = authRoutes.some(route => pathname.startsWith(route) && !pathname.startsWith("/login/fields")) // console.log('🔑 [MIDDLEWARE] 认证状态:', { // isAuthenticated, // pathname, // isProtectedRoute, // isAuthRoute, // token: token ? '存在' : '不存在' // }); // 如果是受保护的路由但用户未登录,重定向到登录页 if (isProtectedRoute && !isAuthenticated) { console.log('🚫 [MIDDLEWARE] 重定向到登录页:', pathname) const loginUrl = new URL("/login", request.url) loginUrl.searchParams.set("redirect", pathname) return NextResponse.redirect(loginUrl) } // 如果已登录用户访问认证页面,重定向到首页 if (isAuthRoute && isAuthenticated) { console.log('🔄 [MIDDLEWARE] 已登录用户重定向到首页:', pathname) return NextResponse.redirect(new URL("/", request.url)) } // 在请求头中添加认证状态和设备ID,供服务端组件使用 const requestHeaders = new Headers(request.headers) requestHeaders.set("x-authenticated", isAuthenticated.toString()) requestHeaders.set("x-device-id", deviceId) // 确保设备ID被传递 if (token) { requestHeaders.set("x-auth-token", token) } // 创建响应 const response = NextResponse.next({ request: { headers: requestHeaders, } }) // 如果需要设置设备ID cookie if (needSetCookie) { response.cookies.set(DEVICE_ID_COOKIE_NAME, deviceId, { maxAge: 365 * 24 * 60 * 60, // 365天 httpOnly: false, secure: process.env.NODE_ENV === 'production', sameSite: 'lax', path: '/' }) } if (pathname.startsWith("/@")) { const userId = pathname.slice(2); // 去掉/@ return NextResponse.rewrite(new URL(`/user/${userId}`, request.url)); } console.log('✅ [MIDDLEWARE] 成功处理完毕:', pathname) return response } export const config = { matcher: [ // 匹配所有路径,除了静态文件和API路由 "/((?!api|_next/static|_next/image|favicon.ico|public).*)", ], }