package controllers import ( "encoding/json" "io" "strings" "time" "server/models" "server/pkg/jwtutil" beego "github.com/beego/beego/v2/server/web" ) // BackendLoginVerifyController 后台登录验证配置 // 对应前端 backend/src/api/sitesettings.js: // - GET /backend/loginVerifyInfos // - POST /backend/saveloginVerifyInfos type BackendLoginVerifyController struct { beego.Controller } func (c *BackendLoginVerifyController) backendLoginVerifyClaims() (*jwtutil.Claims, error) { auth := c.Ctx.Request.Header.Get("Authorization") if auth == "" { return nil, errBackendLoginVerify("未登录") } parts := strings.SplitN(auth, " ", 2) if len(parts) != 2 || parts[0] != "Bearer" { return nil, errBackendLoginVerify("认证信息格式错误") } claims, err := jwtutil.ParseToken(parts[1]) if err != nil { return nil, errBackendLoginVerify("无效的token") } if claims.UserType != "backend" { return nil, errBackendLoginVerify("无权访问") } return claims, nil } type backendLoginVerifyError string func (e backendLoginVerifyError) Error() string { return string(e) } func errBackendLoginVerify(msg string) error { return backendLoginVerifyError(msg) } func (c *BackendLoginVerifyController) jsonErr(httpStatus, bizCode int, msg string) { c.Ctx.Output.SetStatus(httpStatus) c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg} _ = c.ServeJSON() } type backendLoginVerifyPayload struct { OpenVerify *bool `json:"openVerify"` OpenVerifyInt *int8 `json:"openVerify_enabled"` VerifyModel string `json:"verifyModel"` UseGeetest string `json:"use_geetest"` Geetest3ID *string `json:"geetest3ID"` Geetest3IDSnake *string `json:"geetest3_id"` Geetest3Key *string `json:"geetest3KEY"` Geetest3KeySnake *string `json:"geetest3_key"` Geetest4ID *string `json:"geetest4ID"` Geetest4IDSnake *string `json:"geetest4_id"` Geetest4Key *string `json:"geetest4KEY"` Geetest4KeySnake *string `json:"geetest4_key"` } func backendVerifyTypeToModel(v string) string { switch strings.TrimSpace(v) { case "captcha": return "1" case "sms": return "2" case "email": return "3" case "geetest3": return "4" case "geetest", "geetest4": return "5" default: return "1" } } func backendVerifyModelToType(v string) string { switch strings.TrimSpace(v) { case "1": return "captcha" case "2": return "sms" case "3": return "email" case "4": return "geetest3" case "5": return "geetest4" default: switch strings.TrimSpace(v) { case "captcha", "sms", "email", "geetest", "geetest3", "geetest4": return strings.TrimSpace(v) default: return "captcha" } } } func backendStringPtrValue(primary, fallback *string) string { if primary != nil { return *primary } if fallback != nil { return *fallback } return "" } func backendStringPtrOrNil(primary, fallback *string) *string { value := strings.TrimSpace(backendStringPtrValue(primary, fallback)) if value == "" { return nil } return &value } // GetLoginVerifyInfos GET /backend/loginVerifyInfos func (c *BackendLoginVerifyController) GetLoginVerifyInfos() { if _, err := c.backendLoginVerifyClaims(); err != nil { c.jsonErr(401, 401, err.Error()) return } cfg, err := models.GetPlatformLoginVerify() if err != nil { c.jsonErr(500, 500, "获取配置失败") return } openVerify := "0" if cfg.OpenVerifyEnabled == 1 { openVerify = "1" } data := []map[string]string{ {"label": "openVerify", "value": openVerify}, {"label": "verifyModel", "value": backendVerifyTypeToModel(cfg.VerifyType)}, {"label": "geetest3ID", "value": backendStringPtrValue(cfg.Geetest3ID, nil)}, {"label": "geetest3KEY", "value": backendStringPtrValue(cfg.Geetest3Key, nil)}, {"label": "geetest4ID", "value": backendStringPtrValue(cfg.Geetest4ID, nil)}, {"label": "geetest4KEY", "value": backendStringPtrValue(cfg.Geetest4Key, nil)}, } c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": data} _ = c.ServeJSON() } // SaveLoginVerifyInfos POST /backend/saveloginVerifyInfos func (c *BackendLoginVerifyController) SaveLoginVerifyInfos() { if _, err := c.backendLoginVerifyClaims(); err != nil { c.jsonErr(401, 401, err.Error()) return } raw, err := io.ReadAll(c.Ctx.Request.Body) if err != nil { c.jsonErr(400, 400, "参数错误") return } var p backendLoginVerifyPayload if err := json.Unmarshal(raw, &p); err != nil { c.jsonErr(400, 400, "参数错误") return } openVerifyEnabled := int8(0) if p.OpenVerify != nil && *p.OpenVerify { openVerifyEnabled = 1 } if p.OpenVerifyInt != nil { openVerifyEnabled = *p.OpenVerifyInt } verifyModel := p.VerifyModel if strings.TrimSpace(verifyModel) == "" { verifyModel = p.UseGeetest } verifyType := backendVerifyModelToType(verifyModel) geetest3ID := backendStringPtrOrNil(p.Geetest3ID, p.Geetest3IDSnake) geetest3Key := backendStringPtrOrNil(p.Geetest3Key, p.Geetest3KeySnake) geetest4ID := backendStringPtrOrNil(p.Geetest4ID, p.Geetest4IDSnake) geetest4Key := backendStringPtrOrNil(p.Geetest4Key, p.Geetest4KeySnake) if verifyType == "geetest3" { if geetest3ID == nil || geetest3Key == nil { c.jsonErr(400, 400, "极验3.0 ID和KEY不能为空") return } } if verifyType == "geetest4" || verifyType == "geetest" { if geetest4ID == nil || geetest4Key == nil { c.jsonErr(400, 400, "极验4.0 ID和KEY不能为空") return } } now := time.Now() var existed models.PlatformLoginVerify err = models.Orm.QueryTable(new(models.PlatformLoginVerify)).OrderBy("-id").One(&existed) if err == nil { _, err = models.Orm.QueryTable(new(models.PlatformLoginVerify)). Filter("id", existed.ID). Update(map[string]interface{}{ "open_verify_enabled": openVerifyEnabled, "verify_type": verifyType, "geetest3_id": geetest3ID, "geetest3_key": geetest3Key, "geetest4_id": geetest4ID, "geetest4_key": geetest4Key, "update_time": now, }) if err != nil { c.jsonErr(500, 500, "保存失败") return } } else { row := &models.PlatformLoginVerify{ OpenVerifyEnabled: openVerifyEnabled, VerifyType: verifyType, Geetest3ID: geetest3ID, Geetest3Key: geetest3Key, Geetest4ID: geetest4ID, Geetest4Key: geetest4Key, UpdateTime: &now, } if _, err := models.Orm.Insert(row); err != nil { c.jsonErr(500, 500, "保存失败") return } } c.Data["json"] = map[string]interface{}{"code": 200, "msg": "保存成功"} _ = c.ServeJSON() }