fix: stabilize gateway device token reissue

This commit is contained in:
Haitao Pan 2026-06-18 14:48:03 +08:00
parent 28a7eb3343
commit 6a405a00e5
2 changed files with 29 additions and 34 deletions

View File

@ -92,20 +92,7 @@ func handleGatewayConnect(
server.gateway = gatewayruntime.NewManager()
}
result := server.gateway.Connect(request, notify)
if usesBridgeIdentity && shouldRetryOpenClawGatewayWithSharedToken(result) {
clearBridgeGatewayDeviceToken()
request.Auth.DeviceToken = ""
request.HasDeviceToken = false
request.Auth.Token = bridgeSharedAuthToken()
request.HasSharedAuth = strings.TrimSpace(request.Auth.Token) != ""
if request.HasSharedAuth {
request.ConnectAuthMode = "shared-token"
request.ConnectAuthFields = []string{"token"}
request.ConnectAuthSources = []string{"bridge:repair"}
result = server.gateway.Connect(request, notify)
}
}
result := connectOpenClawGateway(server.gateway, request, notify, usesBridgeIdentity)
if result.OK && usesBridgeIdentity {
saveBridgeGatewayDeviceToken(result.ReturnedDeviceToken)
}
@ -297,20 +284,7 @@ func ensureProductionGatewayConnected(
request.Auth.DeviceToken = deviceToken
request.HasDeviceToken = deviceToken != ""
request.ReportedRemoteAddress = resolveGatewayReportedRemoteAddress(server, request)
result := server.gateway.Connect(request, notify)
if shouldRetryOpenClawGatewayWithSharedToken(result) {
clearBridgeGatewayDeviceToken()
request.Auth.DeviceToken = ""
request.HasDeviceToken = false
request.Auth.Token = bridgeSharedAuthToken()
request.HasSharedAuth = strings.TrimSpace(request.Auth.Token) != ""
if request.HasSharedAuth {
request.ConnectAuthMode = "shared-token"
request.ConnectAuthFields = []string{"token"}
request.ConnectAuthSources = []string{"bridge:repair"}
result = server.gateway.Connect(request, notify)
}
}
result := connectOpenClawGateway(server.gateway, request, notify, true)
if result.OK {
saveBridgeGatewayDeviceToken(result.ReturnedDeviceToken)
return nil
@ -323,6 +297,28 @@ func ensureProductionGatewayConnected(
return &shared.RPCError{Code: -32002, Message: "GATEWAY_CONNECT_FAILED: " + message}
}
func connectOpenClawGateway(
manager *gatewayruntime.Manager,
request gatewayruntime.ConnectRequest,
notify func(map[string]any),
usesBridgeIdentity bool,
) gatewayruntime.ConnectResult {
result := manager.Connect(request, notify)
if !usesBridgeIdentity || !shouldRetryOpenClawGatewayWithSharedToken(result) {
return result
}
clearBridgeGatewayDeviceToken()
request.Auth.DeviceToken = ""
request.HasDeviceToken = false
request.Auth.Token = bridgeSharedAuthToken()
request.HasSharedAuth = true
request.ConnectAuthMode = "shared-token"
request.ConnectAuthFields = []string{"token"}
request.ConnectAuthSources = []string{"bridge:device-token-reissue"}
return manager.Connect(request, notify)
}
func shouldRetryOpenClawGatewayWithSharedToken(result gatewayruntime.ConnectResult) bool {
if result.OK || strings.TrimSpace(bridgeSharedAuthToken()) == "" {
return false

View File

@ -360,7 +360,11 @@ func sameConnectTarget(current ConnectRequest, next ConnectRequest) bool {
strings.TrimSpace(current.Endpoint.Host) == strings.TrimSpace(next.Endpoint.Host) &&
current.Endpoint.Port == next.Endpoint.Port &&
current.Endpoint.TLS == next.Endpoint.TLS &&
normalizeEndpointPath(current.Endpoint.Path) == normalizeEndpointPath(next.Endpoint.Path)
normalizeEndpointPath(current.Endpoint.Path) == normalizeEndpointPath(next.Endpoint.Path) &&
strings.TrimSpace(current.Identity.DeviceID) == strings.TrimSpace(next.Identity.DeviceID) &&
strings.TrimSpace(current.Auth.Token) == strings.TrimSpace(next.Auth.Token) &&
strings.TrimSpace(current.Auth.DeviceToken) == strings.TrimSpace(next.Auth.DeviceToken) &&
strings.TrimSpace(current.Auth.Password) == strings.TrimSpace(next.Auth.Password)
}
func (s *session) connectAttempt() (ConnectResult, *GatewayError) {
@ -412,11 +416,6 @@ func (s *session) connectAttempt() (ConnectResult, *GatewayError) {
snapshotPayload := asMap(payload["snapshot"])
sessionDefaults := asMap(snapshotPayload["sessionDefaults"])
returnedDeviceToken := strings.TrimSpace(stringValue(auth["deviceToken"]))
if returnedDeviceToken != "" {
s.mu.Lock()
s.config.Auth.DeviceToken = returnedDeviceToken
s.mu.Unlock()
}
negotiatedScopes := stringSlice(auth["scopes"])
negotiatedRole := strings.TrimSpace(stringValue(auth["role"]))
if negotiatedRole == "" {