电话咨询
This commit is contained in:
@@ -81,13 +81,30 @@ func (s *TokenStore) SaveTokens(ctx context.Context, userID int64, clientType, a
|
||||
|
||||
// ValidateAccessToken 校验 Access Token 是否与 Redis 中存储的一致
|
||||
// clientType 用于定位正确的 Redis key(前台 vs 管理端)
|
||||
// username 用于识别云律临时会议账号,对其放宽「单点登录挤号」校验
|
||||
// username 用于识别云律临时会议账号,对其放宽有状态校验
|
||||
//
|
||||
// 云律临时会议账号(cloudlaw_*)说明:按手机号即时创建、默认口令、仅用于视频/语音会议、角色受限,
|
||||
// 在「双方进会 / SSO 多跳 / 多端 / 重进会议」时会被重复签发,单点登录语义会把先签发的 token 挤掉;
|
||||
// 叠加 Redis key 过期/内存淘汰/重启、登出清理、并发等情况,Redis 侧可能出现「不一致 / 缺失 / 查询失败」。
|
||||
// 由于调用方(中间件/WS 握手)在调用本方法前已用 ParseToken 校验过 JWT 的签名与有效期,
|
||||
// 对这类临时账号只要 JWT 有效即放行(不强依赖 Redis 有状态记录),避免 web-view 进会偶发「认证已失效」。
|
||||
// 普通账号(前台用户/管理端)仍维持严格的有状态校验。
|
||||
func (s *TokenStore) ValidateAccessToken(ctx context.Context, userID int64, clientType, token, username string) bool {
|
||||
funcName := "service.token_store.ValidateAccessToken"
|
||||
|
||||
cloudLaw := isCloudLawUsername(username)
|
||||
|
||||
key := fmt.Sprintf("%s%s:%d", keyPrefixAccessToken, clientType, userID)
|
||||
stored, err := s.redis.Get(ctx, key).Result()
|
||||
if err == redis.Nil {
|
||||
// 云律临时账号:Redis 无记录(挤号后过期 / 内存淘汰 / 重启 / 登出清理)也凭有效 JWT 放行
|
||||
if cloudLaw {
|
||||
logs.Debug(ctx, funcName, "云律临时账号 Redis 无 token 记录,按宽松策略放行(仅凭有效 JWT)",
|
||||
zap.Int64("user_id", userID),
|
||||
zap.String("client_type", clientType),
|
||||
)
|
||||
return true
|
||||
}
|
||||
logs.Debug(ctx, funcName, "Token 不存在(已登出或过期)",
|
||||
zap.Int64("user_id", userID),
|
||||
zap.String("client_type", clientType),
|
||||
@@ -95,6 +112,15 @@ func (s *TokenStore) ValidateAccessToken(ctx context.Context, userID int64, clie
|
||||
return false
|
||||
}
|
||||
if err != nil {
|
||||
// 云律临时账号:Redis 抖动/不可用时凭有效 JWT 放行,避免阻断进会
|
||||
if cloudLaw {
|
||||
logs.Warn(ctx, funcName, "Redis 查询 token 失败,云律临时账号按宽松策略放行(仅凭有效 JWT)",
|
||||
zap.Int64("user_id", userID),
|
||||
zap.String("client_type", clientType),
|
||||
zap.Error(err),
|
||||
)
|
||||
return true
|
||||
}
|
||||
logs.Error(ctx, funcName, "Redis 查询 Token 失败",
|
||||
zap.Int64("user_id", userID),
|
||||
zap.String("client_type", clientType),
|
||||
@@ -107,11 +133,8 @@ func (s *TokenStore) ValidateAccessToken(ctx context.Context, userID int64, clie
|
||||
return true
|
||||
}
|
||||
|
||||
// 云律临时会议账号:同一手机号在「双方进会 / SSO 多跳 / 多端」场景会被重复签发会话,
|
||||
// 单点登录会把先签发的 token 挤掉,导致 web-view 进会报「认证已失效」。
|
||||
// 这里只要该账号在 Redis 中仍存在有效会话(stored 非空,未登出/未过期),
|
||||
// 且 token 已通过 JWT 签名与有效期校验(调用方 ParseToken 已保证),即放行。
|
||||
if stored != "" && isCloudLawUsername(username) {
|
||||
// 云律临时会议账号:token 已被新会话挤号(stored != token)也放行
|
||||
if cloudLaw {
|
||||
logs.Debug(ctx, funcName, "云律临时账号 token 已被新会话覆盖,按宽松策略放行",
|
||||
zap.Int64("user_id", userID),
|
||||
zap.String("client_type", clientType),
|
||||
|
||||
Reference in New Issue
Block a user