You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

104 lines
3.5 KiB

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)
}