import { SsrMiddleWare } from "core/SsrMiddleWare" import bodyParser from "koa-bodyparser" import app from "@/app" import ResponseTime from "./ResponseTime" import Controller from "./Controller" import path from "node:path" import jwt from "jsonwebtoken" import AuthError from "@/utils/error/AuthError" import CommonError from "@/utils/error/CommonError" import { DefaultContext, Next, ParameterizedContext } from "koa" import { AuthMiddleware } from "./Auth" import Session from "./Session" import Send from "./Send" import { getPathByRoot, serverModules, serverPublic } from "helper/path" type App = typeof app export default async (app: App) => { app.use(ResponseTime) // 拦截 Chrome DevTools 探测请求,直接返回 204 app.use((ctx: DefaultContext, next: Next) => { if (ctx.path === "/.well-known/appspecific/com.chrome.devtools.json") { ctx.status = 204 ctx.body = "" return } return next() }) const publicPath = process.env.NODE_ENV === 'production' ? serverPublic : getPathByRoot("public") app.use(async (ctx, next) => { if (!ctx.path.startsWith("/public")) return await next() if (ctx.method.toLowerCase() === "get") { try { await Send(ctx, ctx.path.replace("/public", ""), { root: publicPath, maxAge: 0, immutable: false }) } catch (err: any) { if (err.status !== 404) throw err } } }) app.use(Session(app)) // 权限设置 app.use( AuthMiddleware({ whiteList: [ // 所有请求放行 { pattern: "/" }, { pattern: "/**/*" }, ], blackList: [ // 禁用api请求 // "/api", // "/api/", // "/api/**/*", ], }) ) app.use(bodyParser()) app.use( await Controller({ root: process.env.NODE_ENV === 'production' ? serverModules : path.resolve(__dirname, "../modules"), handleBeforeEachRequest: (options: any) => { const { auth = true } = options || {} return async (ctx: ParameterizedContext, next: Next) => { if (ctx.session && ctx.session.user) { ctx.state.user = ctx.session.user } else { const authorizationString = ctx.headers && ctx.headers["authorization"] if (authorizationString) { const token = authorizationString.replace(/^Bearer\s/, "") try { ctx.state.user = jwt.verify(token, process.env.JWT_SECRET) } catch (_) { // 无效token忽略 } } } if (auth === false && ctx.state.user) { throw new CommonError("不能登录查看") } if (auth === "try") { return next() } if (auth === true && !ctx.state.user) { throw new AuthError("需要登录才能访问") } return await next() } }, }) ) // 处理SSR的插件,理应放在所有路由中间件的最后 await SsrMiddleWare(app) }