Files
History-admin/middleware.ts
2026-04-20 01:37:11 +07:00

74 lines
2.4 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server"
import { PUBLIC_ROUTES, canAccessRoute, UserRole } from "./src/config/routes.config"
/**
* Middleware để kiểm tra authentication và authorization
* Chạy TRƯỚC khi render page
*/
export async function middleware(request: NextRequest) {
const { pathname } = request.nextUrl
// 1. Kiểm tra nếu là public route
if (PUBLIC_ROUTES.includes(pathname)) {
// Nếu user đã login, không cho vào signin/signup
const userDataCookie = request.cookies.get("userDataRedux")
if (userDataCookie && (pathname === "/signin" || pathname === "/signup")) {
return NextResponse.redirect(new URL("/", request.url))
}
return NextResponse.next()
}
// 2. Kiểm tra user data cookie (prioritize này để tránh redirect loop)
const userDataCookie = request.cookies.get("userDataRedux")
if (userDataCookie) {
try {
const userData = JSON.parse(userDataCookie.value)
const userRoles: UserRole[] = userData.roles?.map((r: any) => r.name) || []
// Kiểm tra user có quyền truy cập route này không
if (!canAccessRoute(userRoles, pathname)) {
// Redirect về 403 page
return NextResponse.redirect(new URL("/error-403", request.url))
}
// User có quyền, cho qua
return NextResponse.next()
} catch (error) {
console.error("Error parsing user data in middleware:", error)
// Xóa cookie lỗi
const response = NextResponse.redirect(new URL("/signin", request.url))
response.cookies.delete("userDataRedux")
return response
}
}
// 3. Kiểm tra token từ backend (HTTP-only cookie)
const token = request.cookies.get("token") || request.cookies.get("access_token")
// 4. Nếu không có token và không có user data, redirect về signin
if (!token) {
const signinUrl = new URL("/signin", request.url)
signinUrl.searchParams.set("from", pathname)
return NextResponse.redirect(signinUrl)
}
return NextResponse.next()
}
/**
* Cấu hình matcher - middleware chỉ chạy cho những routes này
*/
export const config = {
matcher: [
/*
* Chạy middleware cho tất cả paths ngoại trừ:
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
* - public folder
*/
"/((?!_next/static|_next/image|favicon.ico|public).*)",
],
}