41 lines
1.4 KiB
TypeScript
41 lines
1.4 KiB
TypeScript
// server/middleware/api-auth.ts - 统一 API 鉴权层,所有非公开 /api/* 请求都必须通过此处
|
||
import { getRequestURL, setResponseStatus } from "h3";
|
||
|
||
import { isPublicApiRoute } from "~~/server/utils/api-auth-rules";
|
||
import { getAuthSession } from "~~/server/utils/auth";
|
||
import { apiErr } from "~~/server/utils/response";
|
||
|
||
/**
|
||
* 统一 API 鉴权 middleware
|
||
*
|
||
* 策略:默认所有 /api/* 需要登录,只有 publicApiRoutes 里的路由可以公开访问。
|
||
* 鉴权通过后将 session 挂到 event.context.auth,handler 直接取用,无需重复查询。
|
||
*
|
||
* 不影响页面渲染、静态资源或 Nuxt 内部请求。
|
||
*/
|
||
export default defineEventHandler(async (event) => {
|
||
const { pathname } = getRequestURL(event);
|
||
const method = event.method;
|
||
|
||
// 只处理 /api/ 路径
|
||
if (!pathname.startsWith("/api/")) return;
|
||
|
||
// OPTIONS 预检请求不需要鉴权;直接返回 204,避免没有匹配 API 路由时落到 404。
|
||
if (method === "OPTIONS") {
|
||
setResponseStatus(event, 204);
|
||
return "";
|
||
}
|
||
|
||
// 公开路由直接放行
|
||
if (isPublicApiRoute(pathname, method)) return;
|
||
|
||
const session = await getAuthSession(event);
|
||
if (!session) {
|
||
setResponseStatus(event, 401);
|
||
return apiErr(401, "unauthorized");
|
||
}
|
||
|
||
// 挂到 event.context,后续 handler 直接读取,不再重复查询 session
|
||
event.context.auth = session;
|
||
});
|