跳到主要内容

会话(Session)

会话(Session)插件用于从当前请求中提取业务侧的 session id,并把它作为请求内共享状态提供给后续插件,同时写入最终请求日志的顶层 session_id 字段。

当前版本只支持从 HTTP header 提取 session id。插件不会把 session id 转发给 upstream,也不会改变鉴权、路由、计费、限速或缓存行为。

启用条件

会话(session)是 route 级插件。只有当前 route 显式配置了 plugin_config.session.id_extractors 时,插件才会进入请求链路;没有静态全局开关,也没有默认 header。

路由级配置通过 RoutePluginConfig 管理接口写入,plugin_key 固定为 sessionconfig 为以下结构的 JSON ProtoJSON 表示:

配置示例

X-Session-ID header 提取:

plugin_config:
session:
id_extractors:
- header:
name: X-Session-ID

id_extractors 是有序数组。运行时会按配置顺序依次尝试,找到第一个 trim 后非空的值就停止。

虽然第一版只实现了 header,配置结构仍保留数组形态,后续可以追加 cookie、query 或 body 等提取方式。

常用配置

Codex 请求通常可以从 session_id header 提取:

plugin_config:
session:
id_extractors:
- header:
name: session_id

Claude Code 请求通常可以从 x-claude-code-session-id header 提取:

plugin_config:
session:
id_extractors:
- header:
name: x-claude-code-session-id

由于 id_extractors 可以配置多个提取器,并且会以找到的第一个非空值为准,也可以直接同时配置这两个 header 来兼容 Codex 和 Claude Code:

plugin_config:
session:
id_extractors:
- header:
name: session_id
- header:
name: x-claude-code-session-id

Header 规则

header.name 必填,且必须是合法 HTTP header field name。

以下情况会被视为配置错误:

  • id_extractors 为空
  • extractor 没有配置已支持的提取方式
  • header.name 为空
  • header.name 不是合法 HTTP header 名

以下情况不会写入 session id:

  • 当前 route 未配置会话(session)插件
  • 请求中没有对应 header
  • header 值 trim 后为空字符串

链路位置

会话(session)插件运行在 Inbound 阶段,并位于日志、入口限速、请求缓存之前。

因此后续插件可以读取同一个请求内提取到的 session id。当前约定的共享状态位置是:

middleware ID / store namespacesession
store keysession_id
valuetrim 后的 session id 字符串

插件之间共享该值时直接通过 mux.Store 的 namespace/key 读取,保持与现有插件共享状态约定一致。

请求日志

提取到的 session id 会写入 logging.v1.RequestLogcore.RequestLog 的顶层 session_id 字段,同时也会写入 ext_fields.session

ext_fields.session 使用以下 proto:

这些字段会出现在:

  • PostgreSQL request_logs.session_id
  • request_logs.raw 中保存的完整请求日志
  • Kafka / HTTP log event 的 request_log.session_id
  • Management API 的请求日志摘要与完整日志响应
  • request_log.ext_fields.session

未配置插件或未提取到值时,顶层 session_id 保持为空,也不会写入 ext_fields.session