import { logger } from "@/logger" import jwt from "./jwt" import { minimatch } from "minimatch" export const JWT_SECRET = process.env.JWT_SECRET function matchList(list, path) { for (const item of list) { if (typeof item === "string" && minimatch(path, item)) { return { matched: true, auth: false } } if (typeof item === "object" && minimatch(path, item.pattern)) { return { matched: true, auth: item.auth } } } return { matched: false } } function verifyToken(ctx) { let token = ctx.headers["authorization"]?.replace(/^Bearer\s/, "") if (!token) { return { ok: false, status: -1 } } try { ctx.state.user = jwt.verify(token, JWT_SECRET) return { ok: true } } catch { ctx.state.user = undefined return { ok: false } } } export default function authMiddleware(options = { whiteList: [], blackList: [] }) { return async (ctx, next) => { if(ctx.session.user) { ctx.state.user = ctx.session.user } // 黑名单优先生效 if (matchList(options.blackList, ctx.path).matched) { ctx.status = 403 ctx.body = { success: false, error: "禁止访问" } return } // 白名单处理 const white = matchList(options.whiteList, ctx.path) if (white.matched) { if (white.auth === false) { return await next() } if (white.auth === "try") { verifyToken(ctx) return await next() } // true 或其他情况,必须有token if (!verifyToken(ctx).ok) { ctx.status = 401 ctx.body = { success: false, error: "未登录或token缺失或无效" } return } return await next() } // 非白名单,必须有token if (!verifyToken(ctx).ok) { ctx.status = 401 ctx.body = { success: false, error: "未登录或token缺失或无效" } return } await next() } }