请求转发
概述
功能概述
请求转发用于在观远 BI 中配置受控的 HTTP 转发入口。管理员将外部服务登记为一个 API 后,超级应用只需要访问观远侧生成的固定地址,观远 BI 会完成权限校验、参数渲染、前置请求执行、敏感凭据注入、目标接口调用、响应返回和审计记录。
适用场景
- 为超级应用提供统一后端入口。
- 隐藏真实目标服务地址,避免前端直接暴露第三方接口。
- 将 token、密码、AK/SK 等敏感信息保存为服务端敏感数据,并在请求中按需引用。
- 在调用目标接口前,先执行登录、换 token、获取临时票据等前置请求。
- 对调用用户、允许来源、日志脱敏和运行调用进行统一管理。
能力边界
- 网关请求方法支持
GET、POST。 - 目标请求方法支持
GET、POST、PUT、DELETE、PATCH。 - 前置请求方法支持
GET、POST。 - 目标 URL 需为合法的
http或https地址。 - 前置请求如需抽取动态参数,响应体需为 JSON,并通过 JSONPath 读取字段。
- 目标接口响应默认透传给调用方,系统会过滤部分不应下发的响应头。
核心概念
API
一个 API 是一条请求转发配置,包含基础信息、权限策略、目标服务、请求参数、前置请求、敏感数据引用和安全配置。
识别符
识别符是 API 的唯一访问路径,也称接口路径或路由编码。例如识别符为 crm-query-user,调用地址就是 https://{bi-host}/api/gateway/routes/crm-query-user。
配置建议:
- 使用业务前缀,例如
crm-query-user、oa-ticket-create。 - 创建后不建议修改,避免影响已经接入的调用方。
- 保持短而清晰,方便排查日志。
敏感数据
敏感数据用于保存敏感凭据,例如第三方 token、密码、AK/SK、client secret 等。配置后,可以在 Headers、Query、Body 或前置请求中通过占位符引用:
${SECRET.crm_client_secret}
敏感数据只在服务端解密和使用。前端展示、审计日志和接口详情中不返回明文。
前置请求
前置请求会在主请求之前执行,常用于登录、获取 token 或换取临时凭证。前置请求执行成功后,可以通过动态参数抽取器从响应 JSON 中提取字段,供主请求使用。
例如前置请求响应为:
{
"accessToken": "token-value"
}
可以配置动态参数:
| 参数名 | JSONPath |
|---|---|
accessToken | $.accessToken |
主请求中即可引用:
${PRE_REQ.accessToken}
访问地址
请求转发 API 的访问地址由 BI 环境域名、固定路径、识别符和可选追加路径组成。
https://{bi-host}/api/gateway/routes/{识别符}
https://{bi-host}/api/gateway/routes/{识别符}/{追加路径1}/{追加路径2}
| 部分 | 说明 | 示例 |
|---|---|---|
{bi-host} | 当前观远 BI 环境域名,不包含结尾 /。 | https://demo.guandata.com |
/api/gateway/routes/ | 请求转发固定访问路径。 | /api/gateway/routes/ |
{识别符} | 新建 API 时配置的唯一识别符。 | crm-query-user |
{追加路径} | 可选,追加在识别符后,用于传递路径参数。 | 123/profile |
例如,识别符为 crm-query-user 时,调用地址为:
https://{bi-host}/api/gateway/routes/crm-query-user
如需通过路径传入用户 ID 和资源类型,可以访问:
https://{bi-host}/api/gateway/routes/user-resource/123/profile
此时系统按顺序生成路径占位符:
| 占位符 | 取值 |
|---|---|
${REQUEST.path.1} | 123 |
${REQUEST.path.2} | profile |
占位符变量
请求转发支持通过占位符把调用方请求、当前用户、前置请求结果和敏感数据注入目标请求。
| 变量 | 含义 | 示例 |
|---|---|---|
${REQUEST.path.n} | 读取识别符后的第 n 个追加路径段。 | ${REQUEST.path.2} 为 /api/gateway/routes/user-resource/123/profile 中读取 profile |
${REQUEST.query.xxx} | 读取调用方 Query 参数。 | ${REQUEST.query.keyword} |
${REQUEST.header.xxx} | 读取调用方普通请求头。 | ${REQUEST.header.x-request-id} |
${REQUEST.body.xxx} | 读取调用方 JSON Body 字段。 | ${REQUEST.body.userId} |
${CURRENT_USER.xxx} | 读取当前登录用户 ID。 | ${CURRENT_USER.userId} |
${PRE_REQ.xxx} | 读取前置请求抽取出的动态参数。 | ${PRE_REQ.accessToken} |
${SECRET.xxx} | 读取敏感数据中保存的敏感值。 | ${SECRET.crm_client_secret} |
${SYSTEM.xxx} | 读取系统内置变量 | ${SYSTEM.current_date} |
注意事项:
- 匿名调用场景下,不建议使用
${CURRENT_USER.xxx}。 - 前置请求中不应依赖尚未产生的
${PRE_REQ.xxx}。 - 只有在请求转发配置中显式定义的 Headers 和 Query 会发送到目标服务。
调用流程
一次完整调用分为以下阶段:
- 请求校验:网关校验识别符、API 状态、请求方法、调用方 Host 和登录权限。
- 前置执行:加载敏感数据,顺序执行前置请求,抽取动态参数。
- 参数渲染:渲染目标 URL、Headers、Query 和 Body 中的占位符。
- 目标调用:按配置发送 Headers、Query 和 Body 到目标服务。
- 响应返回:透传目标服务响应,过滤敏感响应头,记录审计日志。
如果目标服务返回 4xx 或 5xx,网关按目标响应返回给调用方。只有路由不存在、无权限、前置请求失败、目标地址非法、超时等网关侧问题,才返回网关自身错误。
新建请求转发 API
进入观远 BI 「管理中心 > 开放平台 > 请求转发」页面,点击「新建 API」,完成「基础设置」和「请求配置」。

配置流程
配置前建议先确认以下信息:
- 目标接口地址、请求方法和超时时间。
- 目标接口需要的 Headers、Query 参数和 Body。
- 目标接口是否需要登录、鉴权或预先获取 token。
- 调用方使用
GET还是POST访问观远侧网关。 - 调用方是否必须登录,以及允许哪些用户或用户组访问。
- 是否只允许特定页面、系统、域名或 IP 调用。
- 哪些请求头需要在审计日志中脱敏,例如
Authorization、Cookie。
推荐按以下顺序配置:
- 填写基础信息,定义 API 名称、识别符、请求方法和启用状态。
- 配置权限策略和安全策略。
- 配置目标服务地址。
- (可选)如目标接口需要预取 token 或临时凭证,添加前置请求。
- 配置主请求的 Headers、Query、Body 和超时时间。
- 进行接口测试,确认链路正常后启用 API。
基础设置
基础信息
在「基础信息」中定义 API 的基本标识和状态。

| 配置项 | 说明 |
|---|---|
| API 名称 | 管理员可读的 API 名称,例如「CRM 查询用户」。 |
| 识别符 | 网关访问路径的一部分。页面会固定展示 /api/gateway/routes/ 前缀,只需填写后半段,例如 crm-query-user。 |
| 网关请求方法 | 调用方访问观远侧网关时使用的方法,支持 GET、POST。 |
| 目标请求方法 | 网关转发到目标服务时使用的方法,支持 GET、POST、PUT、DELETE、PATCH。 |
| 文档地址 | 可选,填写目标接口或业务说明文档地址。 |
| 启用 | 开启后 API 可被调用;关闭后调用方无法访问该 API。 |
网关请求方法和目标请求方法是两个概念。调用方可以用POST访问观远网关,网关再用PUT调用目标服务。- 识别符创建后不建议修改,避免影响已接入的调用方。
- 识别符建议使用业务前缀,例如
crm-query-user、oa-ticket-create。
权限管理
在「权限管理」中控制谁可以访问该 API。

| 配置项 | 说明 |
|---|---|
| 需要登录 | 开启后,调用方必须提供有效登录态或身份凭证。 |
| 允许访问用户/用户组 | 开启登录后可配置,选择用户/用户组。 为空时,所有已登录用户均可访问;不为空时,仅选中的用户或用户组可访问。 |
生产环境建议默认开启「需要登录」,并按用户组收敛访问范围。若 API 面向外部系统或匿名页面开放,请同时配置允许调用方 Host、日志脱敏 Headers 和目标服务鉴权。
匿名接口不建议使用 ${CURRENT_USER.xxx} 变量。匿名调用没有稳定的当前用户上下文,依赖该变量可能导致参数为空或权限判断不符合预期。
目标服务
在「目标服务」中配置网关最终访问的 URL。目标 URL 支持使用路径占位符动态拼接。

例如调用方访问:
https://{bi-host}/api/gateway/routes/user-resource/123/profile
对应关系为:
| 追加路径段 | 占位符 | 取值 |
|---|---|---|
| 第 1 段 | ${REQUEST.path.1} | 123 |
| 第 2 段 | ${REQUEST.path.2} | profile |
如果目标 URL 配置为:
https://api.example.com/users/${REQUEST.path.1}/resources/${REQUEST.path.2}
则目标服务收到的 URL 为:
https://api.example.com/users/123/resources/profile
Path 参数来自访问地址中识别符后面的追加路径。追加路径不会自动拼到目标 URL 中,只有在请求转发配置中通过 ${REQUEST.path.n} 引用后,才会参与目标请求。
安全配置
在「安全配置」中配置来源限制和日志脱敏规则。

| 配置项 | 说明 |
|---|---|
| 允许的调用方 Host | 多个值用英文逗号分隔。留空表示不限制来源。可填写域名或 IP,例如 example.com,10.0.0.1。 |
| 日志脱敏 Headers | 多个值用英文逗号分隔。命中的 Header 在审计日志中会显示为 ***。 |
常见脱敏配置如下:
Authorization,Cookie,X-Auth-Token
敏感数据替换后的真实值也会在审计日志中脱敏,避免敏感凭据进入日志。
请求配置
完成基础设置后,点击「下一步」进入「请求配置」。

请求配置包含「前置请求」和「主请求配置」。前置请求用于在主请求前获取 token 或临时凭证;主请求配置用于声明如何把调用方请求映射到目标服务。
如果 Headers、Query、Body 或前置请求中需要引用敏感凭据,请先配置敏感数据,再通过 ${SECRET.你的Key} 引用。详见 配置 Secrets。
(可选)前置请求
如果目标接口调用前需要先登录、换 token 或获取临时凭证,可以在「前置请求」区域点击「添加前置请求」。

基础字段

| 字段 | 说明 |
|---|---|
| 请求名称 | 前置请求名称,例如「获取 CRM Token」。 |
| 请求方法 | 支持 GET、POST。 |
| URL | 前置请求的目标地址。 |
| 超时时间 | 前置请求的最长等待时间,单位为秒。 |
| 文档地址 | 可选,填写前置接口的说明文档地址。 |
请求配置

前置请求支持配置 Headers、Query 和 Body。如果请求中需要注入敏感凭据,请先配置敏感数据,再通过 ${SECRET.你的Key} 引用。详见 配置 Secrets。
常见场景是调用登录接口,并在 Body 中注入 client id 和 client secret。
{
"clientId": "${SECRET.crm_client_id}",
"clientSecret": "${SECRET.crm_client_secret}"
}
前置请求中常用变量如下:
| 变量 | 说明 |
|---|---|
${SECRET.xxx} | 读取敏感数据。 |
${CURRENT_USER.xxx} | 读取当前登录用户信息。 |
前置请求接口测试
前置请求编辑弹窗中可以发送测试请求。测试时可以临时修改 Headers、Query 和 Body。

测试时请检查:
- 前置请求能否正常返回。
- 响应体是否为 JSON。
- JSONPath 是否能抽取到预期字段。
- 前置请求中引用的敏感数据是否存在。
前置请求失败时,主请求不会继续执行。
响应参数
「响应参数」用于从前置请求的响应中提取字段。前置请求执行成功后,网关会按照配置的 JSONPath 从响应 JSON 中读取字段,并绑定到自定义参数名上。主请求随后可以通过 ${PRE_REQ.参数名} 引用这些动态参数,例如把 token 注入 Header。

前置请求响应示例:
{
"code": 0,
"data": {
"token": "token-value",
"expiresIn": 7200
}
}
动态参数配置示例:
| 参数名 | 结果字段路径 |
|---|---|
accessToken | $.data.token |
expiresIn | $.data.expiresIn |
主请求中即可引用:
${PRE_REQ.accessToken}
如果配置多个前置请求,请使用清晰且不重复的参数名,例如 crmAccessToken、tenantToken。
主请求配置
在「主请求配置」中定义网关如何组装并发送目标请求,包括 Headers、Query、Body 和超时时间。这里配置的参数才会发送到目标服务;调用方传入但未在此定义的内容,默认不会自动转发。

参数设置
Headers
在「Headers」页签中配置目标服务需要接收的请求头。只有这里配置的 Header 才会发送到目标服务,调用方额外传入但未配置的 Header 不会自动转发。
示例:
| 参数名 | 默认值 | 描述 |
|---|---|---|
Authorization | Bearer ${PRE_REQ.accessToken} | 使用前置请求返回的 token。 |
X-User-Id | ${CURRENT_USER.userId} | 传递当前登录用户 ID。 |
X-Request-Id | ${REQUEST.header.x-request-id} | 读取调用方传入的 x-request-id。 |
如果目标服务需要接收调用方传入的某个 Header,请在这里显式定义,并通过 ${REQUEST.header.xxx} 读取。
Query
在「Query」页签中配置目标服务需要接收的查询参数。只有这里配置的 Queryr 才会发送到目标服务,调用方额外传入但未配置的 Query 不会自动转发。
示例:
| 参数名 | 默认值 | 描述 |
|---|---|---|
keyword | ${REQUEST.query.keyword} | 读取调用方传入的搜索关键词。 |
tenantId | ${CURRENT_USER.tenantId} | 传递当前租户或域信息。 |
如果调用方访问:
https://{bi-host}/api/gateway/routes/crm-query-user?keyword=张三&page=1
但请求转发中只定义了 keyword,则目标服务只会收到 keyword,不会收到 page。
Body
在「Body」页签中配置主请求 Body。调用方传入的 Body 会默认整体透传给目标服务,并在透传前执行占位符替换。
例如调用方传入:
{
"clientId": "${SECRET.crm_client_id}",
"keyword": "张三"
}
转发前,系统会将 ${SECRET.crm_client_id} 替换为敏感数据中保存的真实值,再把完整 Body 发送给目标服务。
配置建议:
- 如果目标接口只需要透传调用方 Body,无需额外配置 Body。
- 如果需要注入敏感数据、当前用户或前置请求结果,可以在 Body 中使用占位符。
- 不建议让不可信调用方随意传入
${...}格式的文本,避免触发非预期变量替换。
超时时间
「超时时间」用于控制目标服务请求的最长等待时间,单位为秒。页面默认值为 120 秒。请根据目标服务的响应性能设置合理值,避免慢接口长期占用请求资源。
主请求接口测试
主请求配置完成后,点击「接口测试」验证完整链路。测试时可以临时修改 Headers、Query 和 Body。调试参数仅用于本次测试,不会保存到 API 配置中。


建议上线前按以下顺序验证:
- 单独测试前置请求,确认能获取 token 或动态参数。
- 检查动态参数 JSONPath 是否能抽取到正确值。
- 测试主请求,确认目标接口状态码、响应体和响应头符合预期。
- 检查审计日志,确认敏感 Headers 和敏感数据已脱敏。
- 启用 API。
- 使用真实调用地址完成一次外部调用验证。
(可选)配置敏感数据
如果目标接口或前置请求需要使用敏感凭据,例如第三方 token、密码、AK/SK、client secret 等,可以在「敏感数据」中统一管理。配置后,在 Headers、Query、Body 或前置请求中通过 ${SECRET.你的Key} 引用。
操作步骤
-
在「请求转发」列表页,点击右上角「敏感数据」,进入敏感数据页面。

-
点击「新建敏感数据」,在弹窗中填写「secretKey」和「密钥值」,点击「确定」保存。

例如配置以下敏感数据:
| Key | Value 示例 |
|---|---|
crm_client_id | mock_client_id_123 |
crm_client_secret | mock_client_secret_456 |
安全规则
- 敏感数据加密保存。
- 前端不返回已保存敏感数据的明文。
- 审计日志中引用敏感数据后的真实值会自动脱敏。
- 删除或修改敏感数据前,请先确认依赖该敏感数据的 API。
配置示例
示例一:简单查询转发(无需前置请求)
目标
超级应用通过观远网关查询 CRM 用户。
基础设置
| 字段 | 值 |
|---|---|
| 识别符 | crm-query-user |
| API 名称 | CRM 查询用户 |
| 网关请求方法 | GET |
| 目标请求方法 | GET |
| 目标 URL | https://crm.example.com/api/users |
主请求 Query 配置
| 参数名 | 默认值 | 说明 |
|---|---|---|
keyword | ${REQUEST.query.keyword} | 读取超级应用传入的查询关键词。 |
前端调用
const response = await fetch(
`/api/gateway/routes/crm-query-user?keyword=${encodeURIComponent("张三")}`,
{
method: "GET",
credentials: "include"
}
);
const result = await response.json();
目标服务收到
GET https://crm.example.com/api/users?keyword=张三
如果前端额外传入 page=1,但请求转发中未定义 page,目标服务不会收到 page。
示例二:先取 token 再调用目标接口
目标
超级应用创建工单,目标系统要求先获取 token。
敏感数据
| Key | 说明 |
|---|---|
crm_client_id | CRM client id。 |
crm_client_secret | CRM client secret。 |
基础设置
| 字段 | 值 |
|---|---|
| 识别符 | crm-create-ticket |
| API 名称 | CRM 创建工单 |
| 网关请求方法 | POST |
| 目标请求方法 | POST |
| 目标 URL | https://crm.example.com/api/tickets |
前置请求
| 字段 | 值 |
|---|---|
| 请求名称 | 获取 CRM Token |
| 请求方法 | POST |
| URL | https://crm.example.com/oauth/token |
| Body | 使用 ${SECRET.crm_client_id} 和 ${SECRET.crm_client_secret} 注入凭据。 |
前置请求 Body
{
"clientId": "${SECRET.crm_client_id}",
"clientSecret": "${SECRET.crm_client_secret}"
}
前置请求响应
{
"accessToken": "token-value"
}
响应参数
| 参数名 | JSONPath |
|---|---|
accessToken | $.accessToken |
主请求 Headers 配置
| 参数名 | 默认值 | 说明 |
|---|---|---|
Authorization | Bearer ${PRE_REQ.accessToken} | 将前置请求获取到的 token 注入目标服务请求头。 |
Content-Type | application/json | 声明请求体格式。 |
前端调用
const response = await fetch("/api/gateway/routes/crm-create-ticket", {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
title: "客户反馈",
priority: "high"
})
});
const result = await response.json();
执行结果
- 网关先调用 token 接口。
- 系统从响应中抽取
accessToken。 - 系统将 token 注入主请求
AuthorizationHeader。 - 网关将调用方 Body 转发给 CRM 创建工单接口。
- 网关将 CRM 响应透传给调用方。
示例三:追加路径转发
目标
超级应用通过路径传入用户 ID 和资源类型。
基础设置
| 字段 | 值 |
|---|---|
| 识别符 | user-resource |
| 网关请求方法 | GET |
| 目标请求方法 | GET |
| 目标 URL | https://api.example.com/users/${REQUEST.path.1}/resources/${REQUEST.path.2} |
前端调用
const userId = "123";
const resourceType = "profile";
const response = await fetch(
`/api/gateway/routes/user-resource/${userId}/${resourceType}`,
{
method: "GET",
credentials: "include"
}
);
路径参数映射
| 追加路径 | 占位符 | 值 |
|---|---|---|
| 第 1 段 | ${REQUEST.path.1} | 123 |
| 第 2 段 | ${REQUEST.path.2} | profile |
目标服务收到
GET https://api.example.com/users/123/resources/profile
运维与审计
响应与错误
正常响应
目标服务正常返回时,网关默认透传:
- HTTP 状态码。
- 响应体。
- 经过安全过滤后的响应头。
以下响应头不会透传:
- 鉴权和会话类:
authorization、proxy-authorization、set-cookie、x-auth-token。 - 连接和传输类:
connection、content-length、transfer-encoding。 - 安全策略类:
content-security-policy、x-frame-options、strict-transport-security。 - CORS 类:以
access-control-、cross-origin-开头的响应头。
网关错误格式
网关自身错误返回统一结构:
{
"success": false,
"code": "GATEWAY_ROUTE_NOT_FOUND",
"message": "gateway route not found",
"data": null
}
常见问题排查
| 问题 | 排查方向 |
|---|---|
| 路由不存在 | 检查识别符是否正确,API 是否已删除。 |
| API 已停用 | 检查 API 状态是否启用。 |
| 请求方法不匹配 | 检查调用方方法是否与网关请求方法一致。 |
| 无权限 | 检查是否已登录、是否在允许用户或用户组中。 |
| 来源不允许 | 检查调用方 Host 是否命中允许调用方 Host。 |
| 前置请求失败 | 单独测试前置请求,检查 URL、Headers、Body、Secrets 和响应格式。 |
| 动态参数为空 | 检查前置请求响应是否为 JSON,JSONPath 是否正确。 |
| 目标接口超时 | 检查目标服务可用性和超时时间配置。 |
| 敏感值未注入 | 检查敏感数据 Key 是否存在,引用格式是否正确。 |
| 目标服务未收到 Header 或 Query | 检查该 Header 或 Query 是否已在请求转发配置中显式定义。 |
审计日志
请求转发会记录三类日志,用于安全审计和问题排查:
- 管理操作日志覆盖 API 和敏感数据的新建、编辑、删除、启停等变更;
- 测试操作日志记录接口测试时的请求摘要、响应状态和结果;
- 运行调用日志记录每一次请求转发调用、前置请求执行、目标服务调用及已脱敏的请求摘要。
在「管理中心 > 运维管理 > 审计日志」中,可查看相应审计日志。

对于日志中的敏感内容,系统会按照脱敏规则处理,避免明文泄露。
| 脱敏对象 | 处理方式 | 示例 |
|---|---|---|
| 命中「日志脱敏 Headers」的请求头 | 值替换为 ***。 | Authorization: *** |
| 敏感数据替换后的真实值 | 写入日志前替换为 ***。 | ${SECRET.crm_client_secret} 的真实值不进入日志。 |
| 常见敏感字段 | 字段名包含 password、token、secret、authorization 等时建议脱敏。 | accessToken: *** |
| Cookie 或会话凭据 | 不记录明文。 | Cookie: *** |
示例:
| 原始 Headers | 写入审计日志 |
|---|---|
Authorization: Bearer eyJhbGciOi... | Authorization: *** |
Cookie: session_id=abc123 | Cookie: *** |
Content-Type: application/json | Content-Type: application/json |
配置建议
- 识别符使用业务前缀,避免跨团队冲突。
- 生产环境默认开启登录校验。
- 面向外部系统开放时,配置允许调用方 Host。
- 敏感数据不要写入普通参数明文,统一放入敏感数据管理。
- 配置日志脱敏 Headers,至少覆盖
Authorization、Cookie、X-Auth-Token。 - 目标服务需要的 Headers 和 Query 必须在请求转发中显式定义。
- 前置请求尽量保持稳定和快速,避免拖慢主请求。
- 动态参数命名要清晰,例如
accessToken、tenantToken。 - 上线前先测试前置请求,再测试完整主请求。
- 修改或删除敏感数据前,先确认依赖该敏感数据的 API。
- 对高风险接口定期检查审计日志和调用来源。