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