依据正常交互式 CLI 抓包修正 Grok 身份头

This commit is contained in:
lyen1688
2026-10-01 12:17:27 +08:00
parent fdce5b8d01
commit ad05eda157
9 changed files with 18 additions and 18 deletions
+1 -1
View File
@@ -39,7 +39,7 @@ func TestApplyCLIBillingHeaders(t *testing.T) {
require.Equal(t, CLITokenAuthValue, req.Header.Get(CLITokenAuthHeader))
require.Equal(t, CLIClientVersion, req.Header.Get(CLIClientVersionHeader))
require.Equal(t, CLIUserAgent(CLIClientVersion), req.UserAgent())
require.Equal(t, "headless", req.Header.Get("x-grok-client-mode"))
require.Equal(t, "interactive", req.Header.Get("x-grok-client-mode"))
}
func TestBuildBillingSummaryWeeklyAndMonthly(t *testing.T) {
+6 -6
View File
@@ -25,11 +25,11 @@ const (
// CLITokenAuth is required by cli-chat-proxy for Grok Build OAuth tokens.
CLITokenAuth = "xai-grok-cli"
// CLIClientIdentifier is the x-grok-client-identifier value used by Grok shell/CLI.
CLIClientIdentifier = "grok-shell"
// CLIClientIdentifier 对齐官方交互式 CLI 主请求的客户端标识。
CLIClientIdentifier = "grok-pager"
// CLIClientMode 对齐官方 CLI 无界面运行模式。
CLIClientMode = "headless"
// CLIClientMode 对齐官方 CLI 正常交互模式。
CLIClientMode = "interactive"
)
// ResolveCLIVersion returns a supported CLI client version.
@@ -55,7 +55,7 @@ func IsSupportedCLIVersion(version string) bool {
semver.Compare(canonical, minimum) >= 0
}
// CLIUserAgent 对齐官方 CLI 无界面模式的 UA,平台名称使用 Rust 的格式。
// CLIUserAgent 对齐官方交互式 CLI 的 UA,平台名称使用 Rust 的格式。
func CLIUserAgent(version string) string {
if strings.TrimSpace(version) == "" {
version = CLIClientVersion
@@ -72,7 +72,7 @@ func CLIUserAgent(version string) string {
case "386":
arch = "x86"
}
return "grok-shell/" + version + " (" + platform + "; " + arch + ")"
return "grok-pager/" + version + " grok-shell/" + version + " (" + platform + "; " + arch + ")"
}
// ApplyCLIProxyHeaders stamps the fixed Grok CLI identity when the request
@@ -28,12 +28,12 @@ func TestApplyCLIProxyHeadersMeetsUpstreamMinimumVersion(t *testing.T) {
}
}
func TestCLIUserAgentMatchesOfficialHeadlessCapture(t *testing.T) {
// 来源:官方 CLI 1.0.46 在 Linux x86_64 的本地 Responses 抓包。
func TestCLIUserAgentMatchesOfficialInteractiveCapture(t *testing.T) {
// 来源:官方 CLI 1.0.46 交互式界面在 Linux x86_64 的主 Responses 请求抓包。
if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
t.Skip("该抓包样本来自 Linux x86_64")
}
require.Equal(t, "grok-shell/1.0.46 (linux; x86_64)", CLIUserAgent("1.0.46"))
require.Equal(t, "grok-pager/1.0.46 grok-shell/1.0.46 (linux; x86_64)", CLIUserAgent("1.0.46"))
}
func TestResolveCLIVersionDefaultsToPinnedClientVersion(t *testing.T) {
@@ -77,7 +77,7 @@ func TestApplyCLIProxyHeaders(t *testing.T) {
require.Equal(t, CLIClientVersion, req.Header.Get("x-grok-client-version"))
require.Equal(t, CLIClientIdentifier, req.Header.Get("x-grok-client-identifier"))
require.Equal(t, CLITokenAuth, req.Header.Get("X-XAI-Token-Auth"))
require.Equal(t, "headless", req.Header.Get("x-grok-client-mode"))
require.Equal(t, "interactive", req.Header.Get("x-grok-client-mode"))
require.Equal(t, "authenticate-response", req.Header.Get("x-authenticateresponse"))
require.Equal(t, CLIUserAgent(CLIClientVersion), req.Header.Get("User-Agent"))
}
@@ -238,8 +238,8 @@ func TestHTTPUpstreamDoAppliesGrokCLIIdentityBeforeOAuthRoundTrip(t *testing.T)
require.Equal(t, xai.CLIClientVersion, capturedHeaders.Get("x-grok-client-version"))
require.Equal(t, "1.0.46", capturedHeaders.Get("x-grok-client-version"))
require.Equal(t, "grok-shell", capturedHeaders.Get("x-grok-client-identifier"))
require.Equal(t, "headless", capturedHeaders.Get("x-grok-client-mode"))
require.Equal(t, "grok-pager", capturedHeaders.Get("x-grok-client-identifier"))
require.Equal(t, "interactive", capturedHeaders.Get("x-grok-client-mode"))
require.Equal(t, "authenticate-response", capturedHeaders.Get("x-authenticateresponse"))
require.Equal(t, "xai-grok-cli", capturedHeaders.Get("X-XAI-Token-Auth"))
require.Equal(t, xai.CLIUserAgent(xai.CLIClientVersion), capturedHeaders.Get("User-Agent"))
@@ -136,7 +136,7 @@ func TestSyncGrokObservedModelsUsesCLIIdentityAndAccountHeaders(t *testing.T) {
require.Equal(t, xai.CLIClientVersion, upstream.lastReq.Header.Get("x-grok-client-version"))
require.Equal(t, xai.CLIClientIdentifier, upstream.lastReq.Header.Get("x-grok-client-identifier"))
require.Equal(t, xai.CLIUserAgent(xai.CLIClientVersion), upstream.lastReq.Header.Get("User-Agent"))
require.Equal(t, "headless", upstream.lastReq.Header.Get("X-Grok-Client-Mode"))
require.Equal(t, "interactive", upstream.lastReq.Header.Get("X-Grok-Client-Mode"))
require.Equal(t, "user-902", upstream.lastReq.Header.Get("X-UserID"))
require.Equal(t, "user902@example.test", upstream.lastReq.Header.Get("X-Email"))
require.Contains(t, repo.updates[account.ID], grokObservedModelsExtraKey)
@@ -17,7 +17,7 @@ const (
grokClientModeHeader = xai.CLIClientMode
)
// defaultGrokUpstreamUserAgent 使用固定版本的官方 CLI 无界面模式 UA。
// defaultGrokUpstreamUserAgent 使用固定版本的官方交互式 CLI UA。
// Grok upstream must not forward Claude Code / Codex / browser client UAs.
func defaultGrokUpstreamUserAgent() string {
return xai.CLIUserAgent(xai.ResolveCLIVersion())
@@ -38,7 +38,7 @@ func TestApplyDefaultGrokUpstreamHeadersHonorsCLIVersionOverride(t *testing.T) {
require.Equal(t, "1.0.14", req.Header.Get("x-grok-client-version"))
require.Equal(t, xai.CLIUserAgent("1.0.14"), req.Header.Get("User-Agent"))
require.Equal(t, "grok-shell", req.Header.Get("x-grok-client-identifier"))
require.Equal(t, "grok-pager", req.Header.Get("x-grok-client-identifier"))
}
func TestResolveGrokUpstreamUserAgentNeverPassthrough(t *testing.T) {
@@ -1613,7 +1613,7 @@ func applyGrokCLIHeaders(headers http.Header) {
headers.Set("X-Grok-Client-Version", version)
headers.Set("x-grok-client-version", version)
headers.Set("x-grok-client-identifier", xai.CLIClientIdentifier)
// 对齐官方 CLI 无界面模式,网关请求与额度探测共用身份。
// 对齐官方 CLI 交互模式,网关请求与额度探测共用身份。
headers.Set("X-Grok-Client-Mode", xai.CLIClientMode)
}
@@ -334,7 +334,7 @@ func TestBuildUpstreamModelsRequestSupportsGrokOAuth(t *testing.T) {
require.Equal(t, "https://cli-chat-proxy.grok.com/v1/models", req.URL.String())
require.Equal(t, "Bearer oauth-access-token", req.Header.Get("Authorization"))
require.Equal(t, grokCLIVersion, req.Header.Get("X-Grok-Client-Version"))
require.Equal(t, "headless", req.Header.Get("X-Grok-Client-Mode"))
require.Equal(t, "interactive", req.Header.Get("X-Grok-Client-Mode"))
require.Equal(t, defaultGrokUpstreamUserAgent(), req.Header.Get("User-Agent"))
require.Equal(t, "grok-user-id", req.Header.Get("X-UserID"))
require.Equal(t, "grok-user@example.com", req.Header.Get("X-Email"))