@@ -131,47 +131,22 @@ func UserLogin(c *gin.Context) {
131131 }
132132 // 登录成功,清除失败记录
133133 limiter .ClearFailures (ip )
134- // 生成token
135- token , err := GetToken (user )
136- if err != nil {
137- utils .Error ("获取token失败: %v" , err )
138- utils .FailWithMsg (c , "获取token失败" )
139- return
140- }
141-
142- // 异步发送登录通知
143- go func (username , ip string ) {
144- location , err := geoip .GetLocation (ip )
134+ if user .TOTPEnabled {
135+ challengeToken , err := issuePendingMFAChallenge (user )
145136 if err != nil {
146- location = "未知位置"
147- }
148- if location == "" {
149- location = "未知位置"
150- }
151- timeStr := time .Now ().Format ("2006-01-02 15:04:05" )
152-
153- payload := notifications.Payload {
154- Title : "用户登录通知" ,
155- Message : fmt .Sprintf ("用户 %s 已登录\n IP: %s (%s)\n 时间: %s" , username , ip , location , timeStr ),
156- Data : map [string ]interface {}{
157- "username" : username ,
158- "ip" : ip ,
159- "location" : location ,
160- "time" : timeStr ,
161- },
162- Time : timeStr ,
137+ utils .Error ("生成 MFA 挑战失败: %v" , err )
138+ utils .FailWithMsg (c , "生成登录验证失败" )
139+ return
163140 }
141+ utils .OkDetailed (c , "需要进行二次验证" , gin.H {
142+ "requiresMFA" : true ,
143+ "challengeToken" : challengeToken ,
144+ "methods" : []string {"totp" , "recovery_code" },
145+ })
146+ return
147+ }
164148
165- notifications .Publish ("security.user_login" , payload )
166- }(username , ip )
167-
168- // 登录成功返回token
169- utils .OkDetailed (c , "登录成功" , gin.H {
170- "accessToken" : token ,
171- "tokenType" : "Bearer" ,
172- "refreshToken" : nil ,
173- "expires" : nil ,
174- })
149+ respondLoginSuccess (c , user , ip )
175150}
176151
177152// UserOut 用户退出登录
@@ -181,3 +156,28 @@ func UserOut(c *gin.Context) {
181156 utils .OkWithMsg (c , "退出成功" )
182157 }
183158}
159+
160+ func notifyUserLogin (username , ip string ) {
161+ location , err := geoip .GetLocation (ip )
162+ if err != nil {
163+ location = "未知位置"
164+ }
165+ if location == "" {
166+ location = "未知位置"
167+ }
168+ timeStr := time .Now ().Format ("2006-01-02 15:04:05" )
169+
170+ payload := notifications.Payload {
171+ Title : "用户登录通知" ,
172+ Message : fmt .Sprintf ("用户 %s 已登录\n IP: %s (%s)\n 时间: %s" , username , ip , location , timeStr ),
173+ Data : map [string ]interface {}{
174+ "username" : username ,
175+ "ip" : ip ,
176+ "location" : location ,
177+ "time" : timeStr ,
178+ },
179+ Time : timeStr ,
180+ }
181+
182+ notifications .Publish ("security.user_login" , payload )
183+ }
0 commit comments