feat: 完善鉴权
This commit is contained in:
Vendored
+1
-17
@@ -1,10 +1,4 @@
|
||||
// server/api/cache/clear.post.ts - 清空答题缓存接口
|
||||
import { setResponseStatus } from "h3";
|
||||
|
||||
import {
|
||||
invalidAccessTokenResponse,
|
||||
verifyAccessToken
|
||||
} from "~~/server/utils/accessToken";
|
||||
import { answerCache } from "~~/server/utils/cache";
|
||||
import { serverEnv } from "~~/server/utils/env";
|
||||
import { createApiLogger } from "~~/server/utils/logging";
|
||||
@@ -12,22 +6,12 @@ import { createApiLogger } from "~~/server/utils/logging";
|
||||
/**
|
||||
* 清空内存缓存
|
||||
*
|
||||
* 这是一个管理类接口,配置 ACCESS_TOKEN 时必须携带正确 token
|
||||
* 这是一个管理类接口,必须携带有效 session cookie(由 api-auth middleware 统一鉴权)
|
||||
* 清理的是当前 Nuxt 进程内缓存;多实例部署时,每个实例都有自己的内存缓存
|
||||
*/
|
||||
export default defineEventHandler((event) => {
|
||||
const logger = createApiLogger(event, "api.cache.clear");
|
||||
|
||||
// 没配置 token 时保持旧服务的开放行为;配置后用于简单保护管理接口
|
||||
if (!verifyAccessToken(event)) {
|
||||
setResponseStatus(event, 403);
|
||||
logger.warn("invalid_access_token");
|
||||
return {
|
||||
success: false,
|
||||
message: invalidAccessTokenResponse().msg
|
||||
};
|
||||
}
|
||||
|
||||
// 缓存被关闭时不报错,只明确告诉调用方当前没有缓存可清
|
||||
if (!serverEnv.enableCache || !answerCache) {
|
||||
return {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// server/api/records.get.ts - 用户问答记录接口,供 Nuxt Dashboard 表格展示
|
||||
import { getQuery, setResponseStatus } from "h3";
|
||||
import { getQuery } from "h3";
|
||||
|
||||
import { getAuthSession } from "~~/server/utils/auth";
|
||||
import { createApiLogger } from "~~/server/utils/logging";
|
||||
import { getQaRecords } from "~~/server/utils/runtimeState";
|
||||
|
||||
@@ -9,27 +8,13 @@ import { getQaRecords } from "~~/server/utils/runtimeState";
|
||||
* 用户问答记录接口(分页,最新在前)
|
||||
*
|
||||
* 安全边界:
|
||||
* - 必须携带有效 session cookie(登录用户)
|
||||
* - 必须携带有效 session cookie(由 api-auth middleware 统一鉴权)
|
||||
* - 只返回当前登录用户自己的记录,用 userId 严格隔离
|
||||
* - 不包含 OpenAI 响应体、API Key 或内部错误
|
||||
*/
|
||||
export default defineEventHandler(async (event) => {
|
||||
const logger = createApiLogger(event, "api.records");
|
||||
|
||||
const session = await getAuthSession(event);
|
||||
if (!session) {
|
||||
setResponseStatus(event, 401);
|
||||
logger.warn("unauthorized");
|
||||
return {
|
||||
success: false,
|
||||
message: "未登录",
|
||||
records: [],
|
||||
page: 1,
|
||||
size: 10,
|
||||
total: 0
|
||||
};
|
||||
}
|
||||
|
||||
const query = getQuery(event);
|
||||
const rawPage = Number.parseInt(query.page?.toString() || "1", 10);
|
||||
const rawSize = Number.parseInt(query.size?.toString() || "10", 10);
|
||||
@@ -38,7 +23,7 @@ export default defineEventHandler(async (event) => {
|
||||
: 10;
|
||||
const page = Number.isFinite(rawPage) ? Math.max(rawPage, 1) : 1;
|
||||
|
||||
const { records, total } = await getQaRecords(session.user.id, {
|
||||
const { records, total } = await getQaRecords(event.context.auth!.user.id, {
|
||||
page,
|
||||
size
|
||||
});
|
||||
|
||||
+1
-18
@@ -1,10 +1,4 @@
|
||||
// server/api/stats.get.ts - 服务运行统计接口
|
||||
import { setResponseStatus } from "h3";
|
||||
|
||||
import {
|
||||
invalidAccessTokenResponse,
|
||||
verifyAccessToken
|
||||
} from "~~/server/utils/accessToken";
|
||||
import { createApiLogger } from "~~/server/utils/logging";
|
||||
import { getRuntimeStats } from "~~/server/utils/runtimeState";
|
||||
|
||||
@@ -12,21 +6,10 @@ import { getRuntimeStats } from "~~/server/utils/runtimeState";
|
||||
* 运行统计接口
|
||||
*
|
||||
* 统计信息包含 uptime、模型名、缓存数量、最近问答记录数量
|
||||
* 因为它能反映服务使用情况,所以和旧 Python 服务一样走可选 ACCESS_TOKEN 校验
|
||||
* 必须携带有效 session cookie(由 api-auth middleware 统一鉴权)
|
||||
*/
|
||||
export default defineEventHandler((event) => {
|
||||
const logger = createApiLogger(event, "api.stats");
|
||||
|
||||
// 未配置 ACCESS_TOKEN 时 verifyAccessToken 会放行;配置后必须携带正确 token
|
||||
if (!verifyAccessToken(event)) {
|
||||
setResponseStatus(event, 403);
|
||||
logger.warn("invalid_access_token");
|
||||
return {
|
||||
success: false,
|
||||
message: invalidAccessTokenResponse().msg
|
||||
};
|
||||
}
|
||||
|
||||
// getRuntimeStats 会实时清理过期缓存,再返回有效缓存数量
|
||||
logger.info("finish_success");
|
||||
return getRuntimeStats();
|
||||
|
||||
@@ -4,21 +4,13 @@ import { randomBytes } from "node:crypto";
|
||||
|
||||
import { setResponseStatus } from "h3";
|
||||
|
||||
import { getAuthSession } from "~~/server/utils/auth";
|
||||
import { prisma } from "~~/server/utils/db";
|
||||
import { createApiLogger } from "~~/server/utils/logging";
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const logger = createApiLogger(event, "api.user.refresh-token");
|
||||
|
||||
const session = await getAuthSession(event);
|
||||
if (!session) {
|
||||
setResponseStatus(event, 401);
|
||||
logger.warn("unauthorized");
|
||||
return { success: false, msg: "未登录" };
|
||||
}
|
||||
|
||||
const userId = session.user.id;
|
||||
const userId = event.context.auth!.user.id;
|
||||
const newToken = randomBytes(16).toString("hex");
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user