feat: openapi auth

This commit is contained in:
archer 2023-05-04 12:18:07 +08:00
parent 487ef670cd
commit c879905307
No known key found for this signature in database
GPG Key ID: 569A5660D2379E28
4 changed files with 41 additions and 31 deletions

View File

@ -1,6 +1,6 @@
import type { NextApiRequest, NextApiResponse } from 'next'; import type { NextApiRequest, NextApiResponse } from 'next';
import { connectToDatabase } from '@/service/mongo'; import { connectToDatabase } from '@/service/mongo';
import { authOpenApiKey, authModel } from '@/service/utils/auth'; import { authOpenApiKey, authModel, getApiKey } from '@/service/utils/auth';
import { modelServiceToolMap, resStreamResponse } from '@/service/utils/chat'; import { modelServiceToolMap, resStreamResponse } from '@/service/utils/chat';
import { ChatItemSimpleType } from '@/types/chat'; import { ChatItemSimpleType } from '@/types/chat';
import { jsonRes } from '@/service/response'; import { jsonRes } from '@/service/response';
@ -28,10 +28,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
try { try {
const { const {
chatId,
prompts, prompts,
modelId, modelId,
isStream = true isStream = true
} = req.body as { } = req.body as {
chatId?: string;
prompts: ChatItemSimpleType[]; prompts: ChatItemSimpleType[];
modelId: string; modelId: string;
isStream: boolean; isStream: boolean;
@ -51,13 +53,20 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
let startTime = Date.now(); let startTime = Date.now();
/* 凭证校验 */ /* 凭证校验 */
const { apiKey, userId } = await authOpenApiKey(req); const { userId } = await authOpenApiKey(req);
const { model } = await authModel({ const { model } = await authModel({
userId, userId,
modelId modelId
}); });
/* get api key */
const { systemAuthKey: apiKey } = await getApiKey({
model: model.chat.chatModel,
userId,
mustPay: true
});
const modelConstantsData = ChatModelMap[model.chat.chatModel]; const modelConstantsData = ChatModelMap[model.chat.chatModel];
// 使用了知识库搜索 // 使用了知识库搜索
@ -98,7 +107,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
apiKey, apiKey,
temperature: +temperature, temperature: +temperature,
messages: prompts, messages: prompts,
stream: isStream stream: isStream,
res,
chatId
}); });
console.log('api response time:', `${(Date.now() - startTime) / 1000}s`); console.log('api response time:', `${(Date.now() - startTime) / 1000}s`);

View File

@ -1,6 +1,6 @@
import type { NextApiRequest, NextApiResponse } from 'next'; import type { NextApiRequest, NextApiResponse } from 'next';
import { connectToDatabase, Model } from '@/service/mongo'; import { connectToDatabase } from '@/service/mongo';
import { authOpenApiKey } from '@/service/utils/auth'; import { authOpenApiKey, authModel, getApiKey } from '@/service/utils/auth';
import { resStreamResponse, modelServiceToolMap } from '@/service/utils/chat'; import { resStreamResponse, modelServiceToolMap } from '@/service/utils/chat';
import { ChatItemSimpleType } from '@/types/chat'; import { ChatItemSimpleType } from '@/types/chat';
import { jsonRes } from '@/service/response'; import { jsonRes } from '@/service/response';
@ -45,13 +45,20 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
let startTime = Date.now(); let startTime = Date.now();
/* 凭证校验 */ /* 凭证校验 */
const { apiKey, userId } = await authOpenApiKey(req); const { userId } = await authOpenApiKey(req);
/* 查找数据库里的模型信息 */ /* 查找数据库里的模型信息 */
const model = await Model.findById(modelId); const { model } = await authModel({
if (!model) { userId,
throw new Error('找不到模型'); modelId
} });
/* get api key */
const { systemAuthKey: apiKey } = await getApiKey({
model: model.chat.chatModel,
userId,
mustPay: true
});
const modelConstantsData = ChatModelMap[model.chat.chatModel]; const modelConstantsData = ChatModelMap[model.chat.chatModel];

View File

@ -56,7 +56,7 @@ export const ERROR_RESPONSE: Record<
data: null data: null
}, },
[ERROR_ENUM.insufficientQuota]: { [ERROR_ENUM.insufficientQuota]: {
code: 403, code: 510,
statusText: ERROR_ENUM.insufficientQuota, statusText: ERROR_ENUM.insufficientQuota,
message: '账号余额不足', message: '账号余额不足',
data: null data: null

View File

@ -29,13 +29,18 @@ export const authToken = (token?: string): Promise<string> => {
}; };
/* 获取 api 请求的 key */ /* 获取 api 请求的 key */
export const getApiKey = async ({ model, userId }: { model: ChatModelType; userId: string }) => { export const getApiKey = async ({
model,
userId,
mustPay = false
}: {
model: ChatModelType;
userId: string;
mustPay?: boolean;
}) => {
const user = await User.findById(userId); const user = await User.findById(userId);
if (!user) { if (!user) {
return Promise.reject({ return Promise.reject(ERROR_ENUM.unAuthorization);
code: 501,
message: '找不到用户'
});
} }
const keyMap = { const keyMap = {
@ -58,7 +63,7 @@ export const getApiKey = async ({ model, userId }: { model: ChatModelType; userI
}; };
// 有自己的key // 有自己的key
if (keyMap[model].userOpenAiKey) { if (!mustPay && keyMap[model].userOpenAiKey) {
return { return {
user, user,
userOpenAiKey: keyMap[model].userOpenAiKey, userOpenAiKey: keyMap[model].userOpenAiKey,
@ -68,10 +73,7 @@ export const getApiKey = async ({ model, userId }: { model: ChatModelType; userI
// 平台账号余额校验 // 平台账号余额校验
if (formatPrice(user.balance) <= 0) { if (formatPrice(user.balance) <= 0) {
return Promise.reject({ return Promise.reject(ERROR_ENUM.unAuthorization);
code: 501,
message: '账号余额不足'
});
} }
return { return {
@ -192,22 +194,12 @@ export const authOpenApiKey = async (req: NextApiRequest) => {
} }
const userId = String(openApi.userId); const userId = String(openApi.userId);
// 余额校验
const user = await User.findById(userId);
if (!user) {
return Promise.reject(ERROR_ENUM.unAuthorization);
}
if (formatPrice(user.balance) <= 0) {
return Promise.reject(ERROR_ENUM.insufficientQuota);
}
// 更新使用的时间 // 更新使用的时间
await OpenApi.findByIdAndUpdate(openApi._id, { await OpenApi.findByIdAndUpdate(openApi._id, {
lastUsedTime: new Date() lastUsedTime: new Date()
}); });
return { return {
apiKey: process.env.OPENAIKEY as string,
userId userId
}; };
} catch (error) { } catch (error) {