会话(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 固定为 session,config 为以下结构的 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 namespace | session |
| store key | session_id |
| value | trim 后的 session id 字符串 |
插件之间共享该值时直接通过 mux.Store 的 namespace/key 读取,保持与现有插件共享状态约定一致。
请求日志
提取到的 session id 会写入 logging.v1.RequestLog 和 core.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。