fix: persist login sessions for workbench auth

This commit is contained in:
richjohnrambo
2026-09-15 10:23:47 +08:00
parent ef8091d805
commit 9ec5da5b02
3 changed files with 55 additions and 1 deletions
+35
View File
@@ -62,6 +62,17 @@ type RealtimeFanoutEnvelope struct {
Message json.RawMessage `json:"message"`
}
type LoginSession struct {
UserID int64 `json:"user_id"`
TenantID int64 `json:"tenant_id"`
TenantCode string `json:"tenant_code"`
DeviceID string `json:"device_id,omitempty"`
AuthLevel string `json:"auth_level"`
State string `json:"state"`
ExpiresAt string `json:"expires_at"`
IssuedAt string `json:"issued_at"`
}
type groupMessageRuntime interface {
Close() error
Claim(tenantID types.TenantID, topic string, from types.Uid, clientMsgID string) (*groupMessageUniqueRecord, bool, error)
@@ -95,6 +106,7 @@ type groupMessageRuntime interface {
ClaimShortState(namespace, id string, ttl time.Duration) (bool, error)
ClaimShortStateValue(namespace, id, value string, ttl time.Duration) (bool, bool, error)
ShortStateExists(namespace, id string) (bool, error)
StoreLoginSession(token []byte, session LoginSession, ttl time.Duration) error
}
var groupMsgRuntime groupMessageRuntime
@@ -190,6 +202,13 @@ func IsLoginTokenRevoked(tenantID types.TenantID, token []byte) (bool, bool, err
return revoked, true, err
}
func StoreLoginSession(token []byte, session LoginSession, ttl time.Duration) (bool, error) {
if groupMsgRuntime == nil || len(token) == 0 || ttl <= 0 {
return false, nil
}
return true, groupMsgRuntime.StoreLoginSession(token, session, ttl)
}
func RefreshUserPresence(tenantID types.TenantID, uid types.Uid, sid, nodeID string) error {
if groupMsgRuntime == nil || !tenantID.IsValid() || uid.IsZero() || sid == "" {
return nil
@@ -990,6 +1009,18 @@ func (r *redisGroupMessageRuntime) ShortStateExists(namespace, id string) (bool,
return count > 0, err
}
func (r *redisGroupMessageRuntime) StoreLoginSession(token []byte, session LoginSession, ttl time.Duration) error {
if len(token) == 0 || ttl <= 0 {
return nil
}
digest := sha256.Sum256(token)
payload, err := json.Marshal(session)
if err != nil {
return err
}
return r.client.Set(context.Background(), r.loginSessionKey(hex.EncodeToString(digest[:])), payload, ttl).Err()
}
func (r *redisGroupMessageRuntime) hotSeqIDs(tenantID types.TenantID, topic string, opts *types.QueryOpt, limit int) ([]int64, bool, error) {
if opts != nil && len(opts.IdRanges) > 0 {
seqs := expandRanges(opts.IdRanges, limit)
@@ -1133,6 +1164,10 @@ func (r *redisGroupMessageRuntime) shortStateKey(namespace, id string) string {
return r.key(types.ZeroTenantID, "short", namespace, id)
}
func (r *redisGroupMessageRuntime) loginSessionKey(tokenHash string) string {
return strings.TrimSuffix(r.prefix, ":") + ":session:token:" + tokenHash
}
func (r *redisGroupMessageRuntime) cacheTTL(namespace string) time.Duration {
ttl := r.cfg.CacheTTL
if namespace == "verification" || namespace == "action_token" {
@@ -171,6 +171,10 @@ func (r *testGroupMessageRuntime) ShortStateExists(namespace, id string) (bool,
return r.shortStates[namespace+":"+id], nil
}
func (r *testGroupMessageRuntime) StoreLoginSession([]byte, LoginSession, time.Duration) error {
return nil
}
func TestLoginTokenRevocation(t *testing.T) {
oldRuntime := groupMsgRuntime
groupMsgRuntime = newTestGroupMessageRuntime()