Files
vless-api/app.js
aixianling dc747d5d43 feat(auth): 添加第三方 token 验证功能
- 新增自定义中间件,用于解析和验证第三方 token
- 添加 verifyThirdPartyToken 模块实现第三方 token 验证逻辑
- 成功验证后,将第三方 token 转换为 JWT token 并设置在请求头中
- 保护所有下方路由,确保只有有效 token 才能访问受保护资源
2025-02-25 11:08:26 +08:00

84 lines
2.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

require("dotenv").config();
const Koa = require("koa");
const Router = require("koa-router");
const jwt = require("jsonwebtoken");
const koaJwt = require("koa-jwt");
const fs = require("fs");
const path = require("path");
const bodyParser = require("koa-bodyparser");
const verifyThirdPartyToken = require("./auth/verifyThirdPartyToken");
const app = new Koa();
app.use(bodyParser()); // 添加在路由中间件之前
const router = new Router();
// 自动加载API路由函数
const loadAPIRoutes = () => {
const apiDir = path.join(__dirname, "api");
const files = fs.readdirSync(apiDir);
files.forEach((file) => {
if (file.endsWith(".js") && file !== "index.js") {
const routePath = `/${file.replace(".js", "")}`;
const handler = require(path.join(apiDir, file));
router.post(routePath, async (ctx) => {
await handler(ctx);
});
}
});
};
// 公开路由
router.get("/public", (ctx) => {
ctx.body = "Public content";
});
// 登录路由
router.post("/login", (ctx) => {
const user = { id: 1, username: "admin" };
const token = jwt.sign(user, process.env.JWT_SECRET, { expiresIn: "1h" });
ctx.body = { token };
});
// 自定义中间件解析并验证第三方Token
app.use(async (ctx, next) => {
const authHeader = ctx.headers.authorization;
if (authHeader && authHeader.startsWith('Bearer ')) {
const thirdPartyToken = authHeader.split(' ')[1];
try {
// 这里假设第三方Token可以通过某种方式验证并转换为JWT Token
const decoded = verifyThirdPartyToken(thirdPartyToken); // 假设有一个验证函数
const jwtToken = jwt.sign(decoded, process.env.JWT_SECRET, { expiresIn: "1h" });
ctx.state.user = user; // 将用户信息存储在ctx.state中
ctx.headers.authorization = `Bearer ${jwtToken}`; // 替换为JWT Token
} catch (err) {
ctx.throw(401, 'Invalid third-party token');
}
}
await next();
});
// JWT中间件保护下方所有路由
app.use(
koaJwt({
secret: process.env.JWT_SECRET,
}).unless({
path: [/^\/public/, /^\/login/],
})
);
// 加载自动生成的路由
loadAPIRoutes();
// 受保护路由
router.get("/protected", (ctx) => {
ctx.body = `Protected content for ${ctx.state.user.username}`;
});
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(process.env.PORT || 3000, () => {
console.log(`Server running on http://localhost:${process.env.PORT || 3000}`);
});