feat: openapi auth
This commit is contained in:
parent
487ef670cd
commit
c879905307
@ -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`);
|
||||||
|
|||||||
@ -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];
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user