Skip to content

feat(login): disable multiple device login policy#649

Merged
LordofAvernus merged 2 commits into
mainfrom
dms/feat-924-disable-multiple-login
Jul 9, 2026
Merged

feat(login): disable multiple device login policy#649
LordofAvernus merged 2 commits into
mainfrom
dms/feat-924-disable-multiple-login

Conversation

@LordofAvernus

@LordofAvernus LordofAvernus commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

User description

Summary

  • Add disable_multiple_login to login configuration API and persistence
  • Track active login sessions and invalidate prior JWTs when the policy is enabled
  • Move GatewayForwardedHeader to shared CE gateway code

Fixes actiontech/dms-ee#924

Test plan

  • CE build: make EDITION=ce docker_install
  • Toggle disable_multiple_login via login configuration API
  • Verify second login invalidates first session when policy is on

Description

  • 新增禁用多设备登录配置

  • 增加登录会话跟踪校验逻辑

  • 更新JWT生成和解析会话ID

  • 调整swagger文档及缓存设计


Diagram Walkthrough

flowchart LR
  A["新增配置字段"] --> B["创建登录会话"]
  B --> C["更新JWT生成逻辑"]
  C --> D["中间件校验会话"]
Loading

File Walkthrough

Relevant files
Enhancement
15 files
configuration.go
添加DisableMultipleLogin字段到登录配置                                                       
+6/-4     
dms_controller.go
增加登录会话创建及JWT增强逻辑                                                                                 
+29/-3   
router.go
添加登录会话中间件检查                                                                                           
+1/-0     
gateway.go
添加网关转发头常量定义                                                                                           
+2/-0     
login_configuration.go
更新登录配置结构及缓存逻辑                                                                                       
+36/-12 
login_configuration_ce.go
修改企业版登录配置参数签名                                                                                       
+4/-3     
login_session.go
新增登录会话管理模块                                                                                             
+101/-0 
oauth2_configuration.go
更新JWT生成以支持会话ID                                                                                     
+18/-9   
user.go
增加记录与查询登录会话方法                                                                                       
+10/-0   
configuration.go
更新登录提示返回结构                                                                                             
+4/-3     
service.go
初始化AuthLoginSessionUsecase模块                                                         
+3/-0     
convert.go
映射登录配置新增字段                                                                                             
+8/-6     
model.go
添加UserLoginSession数据模型                                                                     
+11/-2   
user.go
实现登录会话存储与查询逻辑                                                                                       
+34/-0   
jwt.go
增加会话ID支持及解析方法                                                                                       
+45/-9   
Tests
1 files
op_permission_verify_test.go
添加登录会话相关测试函数                                                                                         
+4/-0     
Documentation
2 files
swagger.json
更新swagger文档新增接口和字段                                                                             
+540/-6 
swagger.yaml
同步swagger定义及接口描述更新                                                                             
+430/-3 
Dependencies
1 files
go.mod
添加go-cache依赖项                                                                                       
+1/-0     

Add login configuration toggle and server-side session tracking.

Fixes actiontech/dms-ee#924
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

PR Reviewer Guide 🔍

(Review updated until commit 123ad4e)

⏱️ Estimated effort to review: 5 🔵🔵🔵🔵🔵
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

代码复用

在处理登录会话ID(如ParseLoginSessionIDFromRefreshToken和WithLoginSessionID)的地方,逻辑与其它JWT处理代码较为相似,建议抽取公共的辅助函数以减少重复代码,从而简化维护。

func ParseLoginSessionIDFromRefreshToken(tokenStr string) (loginSessionID string, err error) {
	token, err := parseJwtTokenStr(tokenStr)
	if err != nil {
		return "", err
	}
	claims, ok := token.Claims.(jwt.MapClaims)
	if !ok {
		return "", fmt.Errorf("failed to convert token claims to jwt")
	}
	if fmt.Sprint(claims[JWTType]) != constant.DMSRefreshToken {
		return "", fmt.Errorf("invalid jwt type")
	}
	loginSessionID, _ = claims[JWTLoginSessionID].(string)
	return loginSessionID, nil
}
安全健壮性建议

在中间件CheckSingleActiveSession中对login session ID的校验仅依赖于其存在性,建议在获取和使用该字段时增加类型和格式的校验,以确保数据符合预期,避免因格式问题导致错误的会话验证。

func (au *AuthLoginSessionUsecase) CheckSingleActiveSession(gatewayForwardedHeader string) echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			if c.Request().Header.Get(gatewayForwardedHeader) != "" {
				return next(c)
			}

			tokenDetail, err := jwtPkg.GetTokenDetailFromContext(c)
			if err != nil {
				return echo.NewHTTPError(http.StatusUnauthorized, fmt.Sprintf("get token detail failed, err:%v", err))
			}
			if tokenDetail.UID == "" {
				return next(c)
			}
			if tokenDetail.LoginType == AccessTokenLogin {
				return next(c)
			}

			disableMultipleLogin, err := au.loginConfigurationUsecase.IsDisableMultipleLogin(c.Request().Context())
			if err != nil {
				return err
			}
			if !disableMultipleLogin {
				return next(c)
			}
			if tokenDetail.LoginSessionID == "" {
				return echo.NewHTTPError(http.StatusUnauthorized, "login session is invalid, please login again")
			}

			latestSessionID, exists, err := au.userUsecase.GetLatestLoginSession(c.Request().Context(), tokenDetail.UID)
			if err != nil {
				return err
			}
			if !exists || latestSessionID != tokenDetail.LoginSessionID {
				return echo.NewHTTPError(http.StatusUnauthorized, "account has been logged in on another device")
			}

			return next(c)
		}

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

Failed to generate code suggestions for PR

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

Persistent review updated to latest commit 123ad4e

@LordofAvernus LordofAvernus merged commit 52c42c6 into main Jul 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants