生产管理系统 - 中间件拦截所有路由
This commit is contained in:
@@ -3,6 +3,21 @@
|
||||
import React, { createContext, useContext, useState, ReactNode } from 'react';
|
||||
import { getCurrentUserInfoApiV1AuthMeGet } from '@/lib/api/sdk.gen';
|
||||
|
||||
// Cookie 操作工具
|
||||
const setTokenCookie = (token: string) => {
|
||||
if (typeof document !== 'undefined') {
|
||||
document.cookie = `auth-token=${token}; path=/; max-age=${7 * 24 * 60 * 60}`;
|
||||
console.log('🍪 Token已设置到cookie');
|
||||
}
|
||||
};
|
||||
|
||||
const removeTokenCookie = () => {
|
||||
if (typeof document !== 'undefined') {
|
||||
document.cookie = 'auth-token=; path=/; max-age=0';
|
||||
console.log('🗑️ Token已从cookie中清除');
|
||||
}
|
||||
};
|
||||
|
||||
interface User {
|
||||
id: string;
|
||||
username: string;
|
||||
@@ -36,12 +51,19 @@ export function AuthProvider({ children }: AuthProviderProps) {
|
||||
setUser(userData);
|
||||
// 存储到 localStorage
|
||||
localStorage.setItem('user', JSON.stringify(userData));
|
||||
|
||||
// 同时设置 cookie(供中间件使用)
|
||||
if (userData.token) {
|
||||
setTokenCookie(userData.token);
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
const logout = () => {
|
||||
setUser(null);
|
||||
localStorage.removeItem('user');
|
||||
removeTokenCookie(); // 清除 cookie
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
@@ -88,6 +110,21 @@ export function AuthProvider({ children }: AuthProviderProps) {
|
||||
|
||||
// 初始化时检查 localStorage并验证用户
|
||||
React.useEffect(() => {
|
||||
// 检查是否有存储的用户信息和 token,并设置 cookie
|
||||
const storedUser = localStorage.getItem('user');
|
||||
if (storedUser) {
|
||||
try {
|
||||
const userData = JSON.parse(storedUser);
|
||||
if (userData.token && !document.cookie.includes('auth-token')) {
|
||||
setTokenCookie(userData.token);
|
||||
console.log('🔄 初始化时设置cookie');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('解析存储用户信息失败:', error);
|
||||
localStorage.removeItem('user');
|
||||
}
|
||||
}
|
||||
|
||||
validateUser();
|
||||
}, []);
|
||||
|
||||
|
||||
75
crop-x/src/middleware.ts
Normal file
75
crop-x/src/middleware.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
// 定义不需要认证的路径
|
||||
const publicPaths = [
|
||||
"/login",
|
||||
"/register",
|
||||
"/api",
|
||||
"/_next",
|
||||
"/favicon.ico",
|
||||
"/static"
|
||||
];
|
||||
|
||||
export async function middleware(request: any) {
|
||||
const { pathname } = request.nextUrl;
|
||||
|
||||
console.log(`🔍 中间件拦截路径: ${pathname}`);
|
||||
|
||||
// 检查是否是公开路径
|
||||
if (publicPaths.some(path => pathname.startsWith(path))) {
|
||||
console.log(`✅ 公开路径,允许访问: ${pathname}`);
|
||||
return NextResponse.next();
|
||||
}
|
||||
|
||||
try {
|
||||
// 从 cookie 中获取 token
|
||||
const token = request.cookies.get("auth-token")?.value;
|
||||
|
||||
console.log(`🍪 Cookie中的token状态: ${token ? '存在' : '不存在'}`);
|
||||
|
||||
// 如果没有 token,重定向到登录页
|
||||
if (!token) {
|
||||
console.log(`🔒 未找到认证 token,重定向到登录页: ${pathname}`);
|
||||
const loginUrl = new URL("/login", request.url);
|
||||
loginUrl.searchParams.set("redirect", pathname);
|
||||
return NextResponse.redirect(loginUrl);
|
||||
}
|
||||
|
||||
// 简单验证 token 格式(不调用API,避免复杂依赖)
|
||||
if (token.length < 10) {
|
||||
console.log(`❌ Token 格式无效,重定向到登录页: ${pathname}`);
|
||||
const loginUrl = new URL("/login", request.url);
|
||||
loginUrl.searchParams.set("redirect", pathname);
|
||||
return NextResponse.redirect(loginUrl);
|
||||
}
|
||||
|
||||
console.log(`✅ Token 存在,允许访问: ${pathname}`);
|
||||
|
||||
// 创建响应并添加用户信息标记
|
||||
const response = NextResponse.next();
|
||||
response.headers.set('x-middleware-auth', 'validated');
|
||||
|
||||
return response;
|
||||
|
||||
} catch (error) {
|
||||
console.error(`❌ 中间件处理失败,重定向到登录页: ${pathname}`, error);
|
||||
// 发生错误时,重定向到登录页
|
||||
const loginUrl = new URL("/login", request.url);
|
||||
loginUrl.searchParams.set("redirect", pathname);
|
||||
return NextResponse.redirect(loginUrl);
|
||||
}
|
||||
}
|
||||
|
||||
export const config = {
|
||||
matcher: [
|
||||
/*
|
||||
* 匹配所有路径除了:
|
||||
* - api (API routes)
|
||||
* - _next/static (static files)
|
||||
* - _next/image (image optimization files)
|
||||
* - favicon.ico (favicon file)
|
||||
* - login 和 register 页面
|
||||
*/
|
||||
"/((?!api|_next/static|_next/image|favicon.ico|login|register).*)",
|
||||
],
|
||||
};
|
||||
Reference in New Issue
Block a user