46 lines
1.7 KiB
TypeScript
46 lines
1.7 KiB
TypeScript
// server/utils/api-auth-rules.ts - API 鉴权路由规则表:声明公开路由,其余默认需要登录
|
||
|
||
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS";
|
||
|
||
type ApiRouteRule = {
|
||
path: string | RegExp;
|
||
method?: HttpMethod | HttpMethod[];
|
||
};
|
||
|
||
/**
|
||
* 公开 API 路由规则表
|
||
*
|
||
* 新增接口默认需要登录,无需任何改动;
|
||
* 只有明确需要公开访问的路由才加到这里。
|
||
*/
|
||
export const publicApiRoutes: ApiRouteRule[] = [
|
||
// Better Auth 自己的登录、注册、退出、get-session 等接口必须放行
|
||
{ path: "/api/auth/**" },
|
||
// 服务健康检查,供部署平台和 Docker healthcheck 使用,不含敏感信息
|
||
{ method: "GET", path: "/api/health" },
|
||
// OCS 油猴脚本跨域无法携带 cookie,搜索接口有自己的双通道鉴权(session 或 apiToken)
|
||
{ path: "/api/search" }
|
||
];
|
||
|
||
/** 路径匹配:支持精确匹配、`/**` 前缀通配和 RegExp */
|
||
const matchPath = (rulePath: string | RegExp, pathname: string): boolean => {
|
||
if (rulePath instanceof RegExp) return rulePath.test(pathname);
|
||
if (rulePath.endsWith("/**")) {
|
||
const prefix = rulePath.slice(0, -3);
|
||
return pathname === prefix || pathname.startsWith(`${prefix}/`);
|
||
}
|
||
return pathname === rulePath;
|
||
};
|
||
|
||
/** 判断当前请求是否命中公开路由规则 */
|
||
export const isPublicApiRoute = (pathname: string, method: string): boolean =>
|
||
publicApiRoutes.some((rule) => {
|
||
const methods = Array.isArray(rule.method)
|
||
? rule.method
|
||
: rule.method
|
||
? [rule.method]
|
||
: null;
|
||
const methodMatched = !methods || methods.includes(method as HttpMethod);
|
||
return methodMatched && matchPath(rule.path, pathname);
|
||
});
|