Commit 85fbe9dc by Archer Committed by GitHub

feat: pro token (#7238)

* feat: pro token

* submodule

* test: fix admin action env
parent 73d13a91
......@@ -5,7 +5,6 @@ stringData:
CHAT_API_KEY: "sk-xxxx"
DB_MAX_LINK: "5"
SYSTEM_MAX_STRING_LENGTH_M: "{{ .Values.system.maxStringLengthM }}"
TOKEN_KEY: "any"
ROOT_KEY: "root_key"
FILE_TOKEN_KEY: "filetoken"
AES256_SECRET_KEY: "fastgptsecret"
......
......@@ -9,7 +9,7 @@ This page covers shared Agent Sandbox configuration for both `opensandbox` and `
### 1. Add the yml service
Use [agent-sandbox-proxy.yml](/deploy/docker/v4.15/agent-proxy.yml) as a reference and add the service to your yml file. Expose the external access port and record the `AGENT_SANDBOX_PROXY_SECRET` value, which you will need in the next step.
Use [agent-sandbox-proxy.yml](/deploy/sandbox_deploy/agent-proxy.yml) as a reference and add the service to your yml file. Expose the external access port and record the `AGENT_SANDBOX_PROXY_SECRET` value, which you will need in the next step.
FastGPT uses this proxy when accessing the sandbox file system.
......
......@@ -9,7 +9,7 @@ description: FastGPT Agent Sandbox 通用配置
### 1. 添加 yml
可以参考 [agent-sandbox-proxy.yml](/deploy/docker/v4.15/agent-proxy.yml),将 service 加到 yml 文件里。并开放外网访问端口。并记录 `AGENT_SANDBOX_PROXY_SECRET` 环境变量,下一步需要使用。
可以参考 [agent-sandbox-proxy.yml](/deploy/sandbox_deploy/agent-proxy.yml),将 service 加到 yml 文件里。并开放外网访问端口。并记录 `AGENT_SANDBOX_PROXY_SECRET` 环境变量,下一步需要使用。
FastGPT 服务里访问沙盒内部文件系统,会通过 proxy 去代理访问。
......
......@@ -16,7 +16,7 @@ The OpenSandbox setup flow is below.
## 1. Add yml services
Use [opensandbox.yml](/deploy/docker/v4.15/opensandbox.yml) as a reference. Add `fastgpt-opensandbox-server`, `fastgpt-volume-manager`, the image pre-pull services, and `opensandbox-config` to your current FastGPT `docker-compose.yml`. Place them on the same `app` network as the FastGPT App service. You do not need to expose OpenSandbox or Volume Manager ports publicly. Deploy Agent Sandbox Proxy separately as described in [General Sandbox Configuration](./common).
Use [opensandbox.yml](/deploy/sandbox_deploy/opensandbox.yml) as a reference. Add `fastgpt-opensandbox-server`, `fastgpt-volume-manager`, the image pre-pull services, and `opensandbox-config` to your current FastGPT `docker-compose.yml`. Place them on the same `app` network as the FastGPT App service. You do not need to expose OpenSandbox or Volume Manager ports publicly. Deploy Agent Sandbox Proxy separately as described in [General Sandbox Configuration](./common).
The sample uses China Mainland image registries. For deployments outside China Mainland, replace them with:
......
......@@ -15,7 +15,7 @@ OpenSandbox 适合需要自托管 Agent/Skill 沙盒运行环境的场景。开
## 1. 添加 yml service
参考 [opensandbox.yml](/deploy/docker/v4.15/opensandbox.yml),将 `fastgpt-opensandbox-server`、`fastgpt-volume-manager`、预拉取镜像和 `opensandbox-config` 加入当前 FastGPT 部署的 `docker-compose.yml`,并放到 FastGPT App 所在的 `app` network 中;不需要对外暴露 OpenSandbox 或 Volume Manager 端口。Agent Sandbox Proxy 请按[沙盒通用配置](./common)单独部署。
参考 [opensandbox.yml](/deploy/sandbox_deploy/opensandbox.yml),将 `fastgpt-opensandbox-server`、`fastgpt-volume-manager`、预拉取镜像和 `opensandbox-config` 加入当前 FastGPT 部署的 `docker-compose.yml`,并放到 FastGPT App 所在的 `app` network 中;不需要对外暴露 OpenSandbox 或 Volume Manager 端口。Agent Sandbox Proxy 请按[沙盒通用配置](./common)单独部署。
下面示例使用国内镜像源。海外部署可将镜像替换为:
......
......@@ -5,6 +5,22 @@ description: 'FastGPT V4.15.1 Release Notes'
## 📦 Upgrade Guide
### Pro Internal API Authentication
Starting from v4.15.1, the FastGPT app no longer uses `rootkey` when calling Pro/Admin internal APIs. These internal service-to-service calls now use a dedicated `PRO_TOKEN`. If you deploy the Pro edition, configure the same `PRO_TOKEN` in both the FastGPT app and the Pro/Admin service:
```bash
PRO_TOKEN=your_pro_token_at_least_32_chars
```
Notes:
1. `PRO_TOKEN` must be at least 32 characters long, and the value must be identical in the FastGPT app and Pro/Admin.
2. If the FastGPT app is configured with `PRO_URL`, `PRO_TOKEN` is also required. Otherwise, the service fails to start.
3. The Pro/Admin service must configure `PRO_TOKEN`; otherwise, internal API authentication fails.
4. `rootkey` is no longer used as the credential for FastGPT app calls to Pro/Admin internal APIs. It is only the admin secret for the current system and is used to call `/api/admin/**` APIs, such as the initialization script below.
5. Open-source deployment files do not include `PRO_TOKEN`. For Pro deployments, add it manually in your private deployment environment variables.
### API Key App Name Initialization
To keep older API keys compatible and make it easier to find keys previously associated with apps, v4.15.1 adds global API Key tag management and an `appName` display snapshot for historical app-level API Keys. After upgrading, run the initialization script once to backfill app names for existing API Keys whose `appId` field is still present.
......
......@@ -5,6 +5,23 @@ description: 'FastGPT V4.15.1 更新说明'
## 📦 升级指南
### fastgpt-pro 环境变量更新
v4.15.1 起,FastGPT 主应用访问 Pro/Admin 内部接口不再使用 `rootkey`,改为使用独立的服务间凭证 `PRO_TOKEN`。同时要求 `FE_DOMAIN` 变量必填,如果你部署了 Pro 版本,需要同时在 FastGPT 主应用和 Pro/Admin 服务中配置相同的 `PRO_TOKEN`:
```bash
PRO_TOKEN=your_pro_token_at_least_32_chars
FE_DOMAIN=fastgpt_domain
```
注意事项:
1. `PRO_TOKEN` 长度必须不少于 32 位,并且主应用与 Pro/Admin 必须保持一致。
2. 如果 FastGPT 主应用配置了 `PRO_URL`,则必须同时配置 `PRO_TOKEN`,否则服务会启动失败。
3. Pro/Admin 服务必须配置 `PRO_TOKEN`,否则内部接口鉴权会失败。
4. `rootkey` 不再作为 FastGPT 主应用访问 Pro/Admin 内部接口的凭证,仅作为当前系统的管理员密钥,用于调用 `/api/admin/**` 接口,例如下方初始化脚本。
5. 开源版部署配置文件不会内置 `PRO_TOKEN`。Pro 部署请在私有部署环境变量中手动增加该配置。
### API Key 应用名初始化
为了兼容旧版 API 密钥,便于找到以前应用关联的密钥,v4.15.1 增加了全局 API Key 标签管理,并为历史应用级 API Key 增加 `appName` 展示快照。升级后建议执行一次初始化脚本,为已有 `appId` 的历史 API Key 自动回填应用名。
......
......@@ -315,7 +315,7 @@
"content/self-host/upgrading/4-15/41507.en.mdx": "2026-06-30T17:31:43+08:00",
"content/self-host/upgrading/4-15/41507.mdx": "2026-06-30T17:31:43+08:00",
"content/self-host/upgrading/4-15/4151.en.mdx": "2026-07-02T09:56:55+08:00",
"content/self-host/upgrading/4-15/4151.mdx": "2026-07-02T09:56:55+08:00",
"content/self-host/upgrading/4-15/4151.mdx": "2026-07-02T11:55:16+08:00",
"content/self-host/upgrading/outdated/40.en.mdx": "2026-04-26T21:08:47+08:00",
"content/self-host/upgrading/outdated/40.mdx": "2026-04-26T21:08:47+08:00",
"content/self-host/upgrading/outdated/41.en.mdx": "2026-04-26T21:08:47+08:00",
......
......@@ -252,7 +252,6 @@ randomize_compose_credentials() {
replace_text 'x-aiproxy-token: &x-aiproxy-token "token"' "x-aiproxy-token: &x-aiproxy-token \"$aiproxy_token\""
# 旧版本没有为这些密钥设置 anchor,需要直接替换环境变量默认值。
replace_text "TOKEN_KEY: fastgpt" "TOKEN_KEY: $token_key"
replace_text "FILE_TOKEN_KEY: filetokenkey" "FILE_TOKEN_KEY: $file_token_key"
replace_text "AES256_SECRET_KEY: fastgptsecret" "AES256_SECRET_KEY: $aes256_secret_key"
replace_text "INVOKE_TOKEN_SECRET: fastgpt_invoke_token_secret_32_chars_min" "INVOKE_TOKEN_SECRET: $invoke_token_secret"
......
......@@ -40,6 +40,7 @@ export const proxyError: Record<string, boolean> = {
export enum ERROR_ENUM {
unAuthorization = 'unAuthorization',
unAuthProToken = 'unAuthProToken',
insufficientQuota = 'insufficientQuota',
unAuthModel = 'unAuthModel',
unAuthApiKey = 'unAuthApiKey',
......@@ -76,6 +77,12 @@ export const ERROR_RESPONSE: Record<
message: i18nT('common:code_error.error_message.403'),
data: null
},
[ERROR_ENUM.unAuthProToken]: {
code: 403,
statusText: ERROR_ENUM.unAuthProToken,
message: 'PRO_TOKEN check error',
data: null
},
[ERROR_ENUM.tooManyRequest]: {
code: 429,
statusText: ERROR_ENUM.tooManyRequest,
......
......@@ -10,3 +10,5 @@ export const isDevEnv = process.env.NODE_ENV === 'development';
export const isProduction = process.env.NODE_ENV === 'production';
export const isTestEnv = process.env.NODE_ENV === 'test';
export const isPhaseProductionBuild = process.env.NEXT_PHASE === 'phase-production-build';
export const FASTGPT_PRO_TOKEN_HEADER = 'x-fastgpt-pro-token';
......@@ -10,19 +10,20 @@ import { createProxyAxios } from './axios';
import { getLogger, LogCategories } from '../logger';
import { assertRelativePath } from '../security/network';
import { serviceEnv } from '../../env';
import { FASTGPT_PRO_TOKEN_HEADER } from '@fastgpt/global/common/system/constants';
const logger = getLogger(LogCategories.HTTP.ERROR);
interface ConfigType {
type ConfigType = {
headers?: { [key: string]: string };
hold?: boolean;
timeout?: number;
}
interface ResponseDataType {
};
type ResponseDataType = {
code: number;
message: string;
data: any;
}
};
/**
* 请求开始
......@@ -70,6 +71,27 @@ function responseError(err: any) {
return Promise.reject(err);
}
/**
* 校验 FastGPT app 服务端访问 pro/admin 的内部请求配置。
*
* 本文件同时保留 GET/POST 等快捷封装和原始 axios config 两种入口;集中处理
* PRO_URL、PRO_TOKEN 和相对路径校验,避免两条入口出现鉴权语义分叉。
*/
const assertInternalProRequestConfig = ({ url }: { url?: string }) => {
if (!FastGPTProUrl) {
logger.warn('FastGPT Pro API is not configured', { url });
throw new UserError('The request was denied...');
}
if (!serviceEnv.PRO_TOKEN) {
logger.error('FastGPT Pro token is not configured', { url });
throw new UserError('FastGPT Pro token is not configured');
}
// plusRequest 仅用于访问商业版 Pro 服务,会自动携带内部 Pro token,SSRF 拦截已被显式关闭。
// 强制要求相对路径,防止调用方传入绝对 URL 覆盖 baseURL 形成带高权限头的 SSRF。
assertRelativePath(url, 'plusRequest');
};
/* 创建请求实例 */
const instance = createProxyAxios(
{
......@@ -77,7 +99,7 @@ const instance = createProxyAxios(
headers: {
'content-type': 'application/json',
'Cache-Control': 'no-cache',
rootkey: serviceEnv.ROOT_KEY
[FASTGPT_PRO_TOKEN_HEADER]: serviceEnv.PRO_TOKEN
}
},
false
......@@ -89,15 +111,8 @@ instance.interceptors.request.use(requestStart, (err) => Promise.reject(err));
instance.interceptors.response.use(responseSuccess, (err) => Promise.reject(err));
export function request(url: string, data: any, config: ConfigType, method: Method): any {
if (!FastGPTProUrl) {
logger.warn('FastGPT Pro API is not configured', { url });
return Promise.reject(new UserError('The request was denied...'));
}
// plusRequest 仅用于访问商业版 Pro 服务,会自动携带 rootkey,SSRF 拦截已被显式关闭。
// 强制要求相对路径,防止调用方传入绝对 URL 覆盖 baseURL 形成带高权限头的 SSRF。
try {
assertRelativePath(url, 'plusRequest');
assertInternalProRequestConfig({ url });
} catch (err) {
return Promise.reject(err);
}
......@@ -147,7 +162,7 @@ export function DELETE<T = undefined>(url: string, data = {}, config: ConfigType
export const plusRequest = (config: AxiosRequestConfig) => {
try {
assertRelativePath(config.url, 'plusRequest');
assertInternalProRequestConfig({ url: config.url });
} catch (err) {
return Promise.reject(err);
}
......
......@@ -35,10 +35,6 @@ export const serviceEnv = createEnv({
.string()
.min(6, 'ROOT_KEY must be at least 6 characters')
.default('fastgpt_root_key'),
TOKEN_KEY: z
.string()
.min(6, 'TOKEN_KEY must be at least 6 characters')
.default('fastgpt_token_key'),
FILE_TOKEN_KEY: z.string().min(6, 'FILE_TOKEN_KEY must be at least 6 characters'),
AES256_SECRET_KEY: z.string().min(6, 'AES256_SECRET_KEY must be at least 6 characters'),
......@@ -61,6 +57,7 @@ export const serviceEnv = createEnv({
CHAT_API_KEY: z.string().optional(),
PRO_URL: UrlSchema.optional(),
PRO_TOKEN: z.string().min(32, 'PRO_TOKEN must be at least 32 characters').optional(),
// Agent sandbox proxy
AGENT_SANDBOX_PROXY_SECRET: z
......@@ -363,6 +360,12 @@ if (serviceEnv.WORKFLOW_PARALLEL_MAX_CONCURRENCY > serviceEnv.WORKFLOW_MAX_LOOP_
}
if (!isPhaseProductionBuild) {
if (serviceEnv.PRO_URL && !serviceEnv.PRO_TOKEN) {
throw new Error(
'Invalid environment configuration: PRO_TOKEN is required when PRO_URL is configured.'
);
}
// 共享 serviceEnv 会被 pro/admin 等项目导入,这里只校验 provider 运行态必填环境变量。
// 主站浏览器直连 agent-sandbox-proxy 的配置由 projects/app 启动流程单独校验。
const missingAgentSandboxEnvKeys = getAgentSandboxMissingRequiredEnvKeys(process.env);
......
......@@ -3,10 +3,11 @@ import { agentSandboxProviderList } from '@fastgpt/global/core/ai/sandbox/consta
import z from 'zod';
const TEST_INVOKE_TOKEN_SECRET = 'fastgpt_test_invoke_token_secret_32';
const TEST_PRO_TOKEN = 'fastgpt_test_pro_token_32_chars_min';
/**
* 测试套件会在多个 workspace(包含 pro/admin 子模块)里直接导入 serviceEnv。
* 生产启动仍要求显式配置 INVOKE_TOKEN_SECRET;仅 Vitest/测试环境允许注入稳定测试密钥,
* 避免每个测试项目都重复维护同一个必填运行时密钥。
* INVOKE_TOKEN_SECRET 生产启动仍要求显式配置;PRO_TOKEN 仅在启用 Pro 内部调用时配置。
* 仅 Vitest/测试环境允许注入稳定测试密钥,避免每个测试项目都重复维护同一组运行时密钥。
*/
export const getRuntimeEnv = (): NodeJS.ProcessEnv => ({
...process.env,
......@@ -14,7 +15,10 @@ export const getRuntimeEnv = (): NodeJS.ProcessEnv => ({
process.env.INVOKE_TOKEN_SECRET ??
(process.env.VITEST === 'true' || process.env.NODE_ENV === 'test'
? TEST_INVOKE_TOKEN_SECRET
: undefined)
: undefined),
PRO_TOKEN:
process.env.PRO_TOKEN ??
(process.env.VITEST === 'true' || process.env.NODE_ENV === 'test' ? TEST_PRO_TOKEN : undefined)
});
/* ===== sandbox ===== */
......
import { afterEach, describe, expect, it, vi } from 'vitest';
import { FASTGPT_PRO_TOKEN_HEADER } from '@fastgpt/global/common/system/constants';
import { createProxyAxios } from '@fastgpt/service/common/api/axios';
const { mockCreateProxyAxios, mockRequest } = vi.hoisted(() => ({
mockCreateProxyAxios: vi.fn(),
mockRequest: vi.fn()
}));
const configuredProToken = 'configured_pro_token_32_chars_min';
vi.mock('@fastgpt/service/common/api/axios', () => ({
createProxyAxios: mockCreateProxyAxios.mockImplementation(() => ({
interceptors: {
request: { use: vi.fn() },
response: { use: vi.fn() }
},
request: mockRequest
}))
}));
const importPlusRequest = async () => {
vi.resetModules();
mockRequest.mockResolvedValue({
data: {
data: { ok: true }
}
});
return import('@fastgpt/service/common/api/plusRequest');
};
describe('plusRequest', () => {
afterEach(() => {
vi.unstubAllEnvs();
vi.resetModules();
mockCreateProxyAxios.mockClear();
mockRequest.mockReset();
});
it('创建请求实例时默认携带 PRO_TOKEN header', async () => {
vi.stubEnv('PRO_URL', 'https://pro.example.com');
vi.stubEnv('PRO_TOKEN', configuredProToken);
await importPlusRequest();
expect(createProxyAxios).toHaveBeenCalledWith(
expect.objectContaining({
headers: expect.objectContaining({
'content-type': 'application/json',
'Cache-Control': 'no-cache',
[FASTGPT_PRO_TOKEN_HEADER]: configuredProToken
})
}),
false
);
});
it('封装请求会校验内部 Pro 请求配置', async () => {
vi.stubEnv('PRO_URL', 'https://pro.example.com');
vi.stubEnv('PRO_TOKEN', configuredProToken);
const { POST } = await importPlusRequest();
await POST(
'/support/test',
{ value: 1 },
{
headers: {
'x-custom-header': 'custom',
[FASTGPT_PRO_TOKEN_HEADER]: 'caller_token'
}
}
);
expect(mockRequest).toHaveBeenCalledWith(
expect.objectContaining({
baseURL: 'https://pro.example.com/api',
url: '/support/test',
headers: expect.objectContaining({
'x-custom-header': 'custom'
})
})
);
});
it('原始 plusRequest 会校验内部 Pro 请求配置', async () => {
vi.stubEnv('PRO_URL', 'https://pro.example.com');
vi.stubEnv('PRO_TOKEN', configuredProToken);
const { plusRequest } = await importPlusRequest();
await plusRequest({
url: '/support/raw',
headers: {
'x-custom-header': 'custom',
[FASTGPT_PRO_TOKEN_HEADER]: 'caller_token'
}
});
expect(mockRequest).toHaveBeenCalledWith(
expect.objectContaining({
baseURL: 'https://pro.example.com/api',
url: '/support/raw',
headers: expect.objectContaining({
'x-custom-header': 'custom'
})
})
);
});
});
......@@ -8,6 +8,8 @@ const originalEnv = {
FILE_TOKEN_KEY: process.env.FILE_TOKEN_KEY,
AES256_SECRET_KEY: process.env.AES256_SECRET_KEY,
INVOKE_TOKEN_SECRET: process.env.INVOKE_TOKEN_SECRET,
PRO_URL: process.env.PRO_URL,
PRO_TOKEN: process.env.PRO_TOKEN,
VITEST: process.env.VITEST,
NODE_ENV: process.env.NODE_ENV,
AGENT_SANDBOX_PROVIDER: process.env.AGENT_SANDBOX_PROVIDER,
......@@ -32,6 +34,8 @@ describe('serviceEnv', () => {
vi.stubEnv('FILE_TOKEN_KEY', originalEnv.FILE_TOKEN_KEY);
vi.stubEnv('AES256_SECRET_KEY', originalEnv.AES256_SECRET_KEY);
vi.stubEnv('INVOKE_TOKEN_SECRET', originalEnv.INVOKE_TOKEN_SECRET);
vi.stubEnv('PRO_URL', originalEnv.PRO_URL);
vi.stubEnv('PRO_TOKEN', originalEnv.PRO_TOKEN);
vi.stubEnv('VITEST', originalEnv.VITEST);
vi.stubEnv('NODE_ENV', originalEnv.NODE_ENV);
vi.stubEnv('AGENT_SANDBOX_PROVIDER', originalEnv.AGENT_SANDBOX_PROVIDER);
......@@ -113,6 +117,61 @@ describe('serviceEnv', () => {
});
});
it('uses PRO_TOKEN only when configured or running tests', async () => {
vi.stubEnv('FILE_TOKEN_KEY', 'filetokenkey');
vi.stubEnv('AES256_SECRET_KEY', 'fastgptsecret');
vi.stubEnv('INVOKE_TOKEN_SECRET', validInvokeTokenSecret);
vi.stubEnv('PRO_URL', undefined);
vi.stubEnv('PRO_TOKEN', undefined);
vi.stubEnv('VITEST', undefined);
vi.stubEnv('NODE_ENV', 'production');
await expect(importServiceEnv()).resolves.toMatchObject({
serviceEnv: {
PRO_TOKEN: undefined
}
});
vi.stubEnv('VITEST', 'true');
await expect(importServiceEnv()).resolves.toMatchObject({
serviceEnv: {
PRO_TOKEN: 'fastgpt_test_pro_token_32_chars_min'
}
});
vi.stubEnv('PRO_TOKEN', 'custom_pro_token_32_chars_minimum');
await expect(importServiceEnv()).resolves.toMatchObject({
serviceEnv: {
PRO_TOKEN: 'custom_pro_token_32_chars_minimum'
}
});
});
it('配置 PRO_URL 后必须同时配置合法 PRO_TOKEN', async () => {
vi.stubEnv('FILE_TOKEN_KEY', 'filetokenkey');
vi.stubEnv('AES256_SECRET_KEY', 'fastgptsecret');
vi.stubEnv('INVOKE_TOKEN_SECRET', validInvokeTokenSecret);
vi.stubEnv('VITEST', undefined);
vi.stubEnv('NODE_ENV', 'production');
vi.stubEnv('PRO_URL', 'https://pro.example.com');
vi.stubEnv('PRO_TOKEN', undefined);
await expect(importServiceEnv()).rejects.toThrow(
'PRO_TOKEN is required when PRO_URL is configured'
);
vi.stubEnv('PRO_TOKEN', 'short-token');
await expect(importServiceEnv()).rejects.toThrow('Invalid environment variables');
vi.stubEnv('PRO_TOKEN', 'custom_pro_token_32_chars_minimum');
await expect(importServiceEnv()).resolves.toMatchObject({
serviceEnv: {
PRO_URL: 'https://pro.example.com',
PRO_TOKEN: 'custom_pro_token_32_chars_minimum'
}
});
});
it('validates AGENT_SANDBOX_DISK_MB during service env init', async () => {
vi.stubEnv('FILE_TOKEN_KEY', 'filetokenkey');
vi.stubEnv('AES256_SECRET_KEY', 'fastgptsecret');
......
......@@ -924,6 +924,9 @@ importers:
'@scalar/api-reference-react':
specifier: ^0.8.1
version: 0.8.1(axios@1.16.0)(nprogress@0.2.0)(qrcode@1.5.4)(react@18.3.1)(tailwindcss@3.4.18(tsx@4.20.6)(yaml@2.8.4))(typescript@6.0.3)
'@t3-oss/env-core':
specifier: 'catalog:'
version: 0.13.10(typescript@6.0.3)(zod@4.1.12)
'@tanstack/react-query':
specifier: 'catalog:'
version: 4.36.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
Subproject commit 120262a5c3bdf2b0a7b7d16a851ad200dfe6edcb
Subproject commit b705b31d509d54457aeee463322f93b974b741d3
......@@ -8,8 +8,6 @@ DB_MAX_LINK=5
SYNC_INDEX=true
# ==================== 密钥 ====================
# 用户账号密钥
TOKEN_KEY=fastgpt
# 文件阅读时的密钥
FILE_TOKEN_KEY=
# 密钥加密 key
......@@ -19,9 +17,11 @@ INVOKE_TOKEN_SECRET=fastgpt_invoke_token_secret_32_chars_min
# root key(最高权限)
ROOT_KEY=fdafasd
# ==================== 服务地址与集成 ====================
# 商业版地址
# PRO_URL=
# PRO_TOKEN=
# 插件服务
PLUGIN_BASE_URL=http://localhost:3004
......@@ -264,4 +264,4 @@ VECTOR_MAX_PROCESS=10
# 问答拆分队列最大并发数
QA_MAX_PROCESS=10
# 图片理解模型处理队列最大并发数
VLM_MAX_PROCESS=10
\ No newline at end of file
VLM_MAX_PROCESS=10
......@@ -3,6 +3,7 @@ import { jsonRes } from '@fastgpt/service/common/response';
import { FastGPTProUrl } from '@fastgpt/service/common/system/constants';
import { buildSameOriginUrl } from '@fastgpt/service/common/security/network';
import { Readable } from 'stream';
import { FASTGPT_PRO_TOKEN_HEADER } from '@fastgpt/global/common/system/constants';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
......@@ -21,7 +22,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const headers: Record<string, string> = {};
for (const [key, value] of Object.entries(req.headers)) {
if (key === 'rootkey' || key === 'host' || key === 'connection') continue;
if (
key === 'rootkey' ||
key === FASTGPT_PRO_TOKEN_HEADER ||
key === 'host' ||
key === 'connection'
) {
continue;
}
if (value) {
headers[key] = Array.isArray(value) ? value.join(', ') : value;
}
......
......@@ -39,9 +39,9 @@ export const instrumentationCheck = async () => {
// pro
if (global.feConfigs?.isPlus) {
try {
const data = await POST<{ auth: boolean; data: string }>('/admin/common/health');
const data = await POST<{ auth: boolean; data: string }>('/health');
if (!data.auth) {
throw new Error('Root key is invalid');
throw new Error('PRO_TOKEN is invalid');
}
} catch (error) {
const message = `[${InitialErrorEnum.PRO_ERROR}]: ${getErrText(error)}`;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment