ChatGPT-Next-Web/app/api/auth.ts

124 lines
3.6 KiB
TypeScript

import type { NextRequest } from 'next/server';
import md5 from 'spark-md5';
import { getServerSideConfig } from '../config/server';
import { ACCESS_CODE_PREFIX, ModelProvider } from '../constant';
function getIP(req: NextRequest) {
let ip = req.ip ?? req.headers.get('x-real-ip');
const forwardedFor = req.headers.get('x-forwarded-for');
if (!ip && forwardedFor) {
ip = forwardedFor.split(',').at(0) ?? '';
}
return ip;
}
function parseApiKey(bearToken: string) {
const token = bearToken.trim().replaceAll('Bearer ', '').trim();
const isApiKey = !token.startsWith(ACCESS_CODE_PREFIX);
return {
accessCode: isApiKey ? '' : token.slice(ACCESS_CODE_PREFIX.length),
apiKey: isApiKey ? token : '',
};
}
export function auth(req: NextRequest, modelProvider: ModelProvider) {
const authToken = req.headers.get('Authorization') ?? '';
// check if it is openai api key or user token
const { accessCode, apiKey } = parseApiKey(authToken);
const hashedCode = md5.hash(accessCode ?? '').trim();
const serverConfig = getServerSideConfig();
console.log('[Auth] allowed hashed codes: ', [...serverConfig.codes]);
console.log('[Auth] got access code:', accessCode);
console.log('[Auth] hashed access code:', hashedCode);
console.log('[User IP] ', getIP(req));
console.log('[Time] ', new Date().toLocaleString());
if (serverConfig.needCode && !serverConfig.codes.has(hashedCode) && !apiKey) {
return {
error: true,
msg: !accessCode ? 'empty access code' : 'wrong access code',
};
}
if (serverConfig.hideUserApiKey && !!apiKey) {
return {
error: true,
msg: 'you are not allowed to access with your own api key',
};
}
// if user does not provide an api key, inject system api key
if (!apiKey) {
const serverConfig = getServerSideConfig();
// const systemApiKey =
// modelProvider === ModelProvider.GeminiPro
// ? serverConfig.googleApiKey
// : serverConfig.isAzure
// ? serverConfig.azureApiKey
// : serverConfig.apiKey;
let systemApiKey: string | undefined;
switch (modelProvider) {
case ModelProvider.Stability:
systemApiKey = serverConfig.stabilityApiKey;
break;
case ModelProvider.GeminiPro:
systemApiKey = serverConfig.googleApiKey;
break;
case ModelProvider.Claude:
systemApiKey = serverConfig.anthropicApiKey;
break;
case ModelProvider.Doubao:
systemApiKey = serverConfig.bytedanceApiKey;
break;
case ModelProvider.Ernie:
systemApiKey = serverConfig.baiduApiKey;
break;
case ModelProvider.Qwen:
systemApiKey = serverConfig.alibabaApiKey;
break;
case ModelProvider.Moonshot:
systemApiKey = serverConfig.moonshotApiKey;
break;
case ModelProvider.Iflytek:
systemApiKey
= `${serverConfig.iflytekApiKey}:${serverConfig.iflytekApiSecret}`;
break;
case ModelProvider.XAI:
systemApiKey = serverConfig.xaiApiKey;
break;
case ModelProvider.ChatGLM:
systemApiKey = serverConfig.chatglmApiKey;
break;
case ModelProvider.GPT:
default:
if (req.nextUrl.pathname.includes('azure/deployments')) {
systemApiKey = serverConfig.azureApiKey;
} else {
systemApiKey = serverConfig.apiKey;
}
}
if (systemApiKey) {
console.log('[Auth] use system api key');
req.headers.set('Authorization', `Bearer ${systemApiKey}`);
} else {
console.log('[Auth] admin did not provide an api key');
}
} else {
console.log('[Auth] use user api key');
}
return {
error: false,
};
}