做几方面优化

This commit is contained in:
2026-09-25 00:27:15 +08:00
parent eafa5e1cf4
commit 92403171d4
14 changed files with 2142 additions and 258 deletions
+35 -14
View File
@@ -81,6 +81,12 @@ func (c *AuthLoginController) LoginSubmit() {
ClientID string `json:"client_id"`
Redirect string `json:"redirect"`
DeviceID string `json:"device_id"`
// 极验 4.0 验证结果:开启人机验证后由前端 SDK 产出,验证通过才允许继续登录
CaptchaID string `json:"captcha_id"`
LotNumber string `json:"lot_number"`
PassToken string `json:"pass_token"`
GenTime string `json:"gen_time"`
CaptchaOutput string `json:"captcha_output"`
}
body := c.Ctx.Input.RequestBody
@@ -101,6 +107,18 @@ func (c *AuthLoginController) LoginSubmit() {
return
}
// 开启人机验证时:先极验通过,再走账号密码校验
if err := authsvc.VerifyLoginCaptcha(0, authsvc.CaptchaResult{
CaptchaID: req.CaptchaID,
LotNumber: req.LotNumber,
PassToken: req.PassToken,
GenTime: req.GenTime,
CaptchaOutput: req.CaptchaOutput,
}); err != nil {
c.serveJSON(map[string]interface{}{"code": 400, "msg": err.Error()})
return
}
clientIP := c.Ctx.Input.IP()
userAgent := c.Ctx.Request.UserAgent()
@@ -309,28 +327,31 @@ func (c *AuthLoginController) LogoutAction() {
c.serveJSON(map[string]interface{}{"code": 200, "msg": "已登出"})
}
// VerifyConfig 租户登录验证配置(替代 /backend/login/getOpenVerify)
// VerifyConfig 登录验证配置(替代 /backend/login/getOpenVerify)
// GET /auth/verify-config?tid=
//
// 登录页在选企业之前调用,tid 可为空:此时以平台全局配置为准。
// 返回的人机验证信息供登录页决定是否在点击登录后弹出极验。
func (c *AuthLoginController) VerifyConfig() {
tid, _ := c.GetInt64("tid", 0)
cfg := authsvc.GetTenantSessionPolicy(uint64(tid))
sessionCfg := authsvc.GetTenantSessionPolicy(uint64(tid))
verify := authsvc.GetLoginVerifyConfig(uint64(tid))
var authCfg models.AuthTenantAuthConfig
verifyType := "captcha"
openVerify := 1
if err := models.Orm.QueryTable(new(models.AuthTenantAuthConfig)).
Filter("tid", tid).One(&authCfg); err == nil {
verifyType = authCfg.VerifyType
openVerify = int(authCfg.OpenVerify)
openVerify := 0
if verify.OpenVerify {
openVerify = 1
}
c.serveJSON(map[string]interface{}{
"code": 200,
"data": map[string]interface{}{
"openVerify": openVerify,
"verifyType": verifyType,
"sessionTTL": cfg.SessionTTL,
"maxSession": cfg.MaxSession,
"mfaRequired": 0,
"openVerify": openVerify,
"verifyType": verify.VerifyType,
"needGeetest": verify.NeedGeetest(),
"geetestVersion": verify.GeetestVersion,
"captchaId": verify.CaptchaID,
"sessionTTL": sessionCfg.SessionTTL,
"maxSession": sessionCfg.MaxSession,
"mfaRequired": 0,
},
})
}
+15 -4
View File
@@ -282,11 +282,22 @@ func (c *AuthOidcController) UserInfo() {
name = profile.Nickname
}
// 当前会话所在企业名称(一人多企业时必须是"已选中的那一家",
// 而非全部可进入企业;前端直接展示该字段,避免自行拼接 tenants)
tenantName := ""
for _, t := range profile.Tenants {
if t.Tid == uint64(claims.TenantId) {
tenantName = t.TenantName
break
}
}
c.serveJSON(map[string]interface{}{
"sub": fmt.Sprintf("%d", identity.ID),
"id": identity.ID,
"union_id": identity.UnionID,
"tid": claims.TenantId,
"sub": fmt.Sprintf("%d", identity.ID),
"id": identity.ID,
"union_id": identity.UnionID,
"tid": claims.TenantId,
"tenant_name": tenantName,
// 诊断用:业务接口按 user_type 判定权限(backend / app),
// 出现「无权访问」时可先看这里的值是否正确
"user_type": claims.UserType,
+121 -105
View File
@@ -1,105 +1,121 @@
package controllers
import (
"encoding/json"
"io"
"strings"
"server/models"
beego "github.com/beego/beego/v2/server/web"
)
type PlatformLoginVerifyController struct {
beego.Controller
}
type loginVerifyPayload struct {
OpenVerifyEnabled *int8 `json:"openVerify_enabled"`
VerifyType string `json:"use_geetest"`
Geetest3ID *string `json:"geetest3_id"`
Geetest3Key *string `json:"geetest3_key"`
Geetest4ID *string `json:"geetest4_id"`
Geetest4Key *string `json:"geetest4_key"`
}
func normalizeVerifyType(v string) string {
switch strings.TrimSpace(v) {
case "sms", "geetest", "email", "captcha":
return strings.TrimSpace(v)
default:
return "captcha"
}
}
// GetLoginVerifyInfos 获取登录验证配置
// GET /platform/loginVerifyInfos
func (c *PlatformLoginVerifyController) GetLoginVerifyInfos() {
cfg, err := models.GetPlatformLoginVerify()
if err != nil {
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "获取配置失败"}
_ = c.ServeJSON()
return
}
c.Data["json"] = map[string]interface{}{
"code": 200,
"msg": "success",
"data": map[string]interface{}{
"openVerify_enabled": cfg.OpenVerifyEnabled,
"use_geetest": cfg.VerifyType,
"geetest3_id": cfg.Geetest3ID,
"geetest3_key": cfg.Geetest3Key,
"geetest4_id": cfg.Geetest4ID,
"geetest4_key": cfg.Geetest4Key,
},
}
_ = c.ServeJSON()
}
// SaveLoginVerifyInfos 保存登录验证配置
// POST /platform/saveloginVerifyInfos
func (c *PlatformLoginVerifyController) SaveLoginVerifyInfos() {
var p loginVerifyPayload
raw, _ := io.ReadAll(c.Ctx.Request.Body)
if err := json.Unmarshal(raw, &p); err != nil {
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "参数错误"}
_ = c.ServeJSON()
return
}
verifyType := normalizeVerifyType(p.VerifyType)
openVerifyEnabled := int8(1)
if p.OpenVerifyEnabled != nil {
openVerifyEnabled = *p.OpenVerifyEnabled
}
if verifyType == "geetest" {
if p.Geetest4ID == nil || strings.TrimSpace(*p.Geetest4ID) == "" {
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "geetest4_id 不能为空"}
_ = c.ServeJSON()
return
}
if p.Geetest4Key == nil || strings.TrimSpace(*p.Geetest4Key) == "" {
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "geetest4_key 不能为空"}
_ = c.ServeJSON()
return
}
}
err := models.SavePlatformLoginVerify(&models.PlatformLoginVerify{
OpenVerifyEnabled: openVerifyEnabled,
VerifyType: verifyType,
Geetest3ID: p.Geetest3ID,
Geetest3Key: p.Geetest3Key,
Geetest4ID: p.Geetest4ID,
Geetest4Key: p.Geetest4Key,
})
if err != nil {
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "保存失败"}
_ = c.ServeJSON()
return
}
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "保存成功"}
_ = c.ServeJSON()
}
package controllers
import (
"encoding/json"
"io"
"strings"
"server/models"
authsvc "server/services/auth"
beego "github.com/beego/beego/v2/server/web"
)
type PlatformLoginVerifyController struct {
beego.Controller
}
type loginVerifyPayload struct {
OpenVerifyEnabled *int8 `json:"openVerify_enabled"`
VerifyType string `json:"use_geetest"`
Geetest3ID *string `json:"geetest3_id"`
Geetest3Key *string `json:"geetest3_key"`
Geetest4ID *string `json:"geetest4_id"`
Geetest4Key *string `json:"geetest4_key"`
}
func normalizeVerifyType(v string) string {
switch strings.TrimSpace(v) {
case "sms", "geetest", "email", "captcha":
return strings.TrimSpace(v)
default:
return "captcha"
}
}
// GetLoginVerifyInfos 获取登录验证配置
// GET /platform/loginVerifyInfos
func (c *PlatformLoginVerifyController) GetLoginVerifyInfos() {
cfg, err := models.GetPlatformLoginVerify()
if err != nil {
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "获取配置失败"}
_ = c.ServeJSON()
return
}
c.Data["json"] = map[string]interface{}{
"code": 200,
"msg": "success",
"data": map[string]interface{}{
"openVerify_enabled": cfg.OpenVerifyEnabled,
"use_geetest": cfg.VerifyType,
"geetest3_id": cfg.Geetest3ID,
"geetest3_key": cfg.Geetest3Key,
"geetest4_id": cfg.Geetest4ID,
"geetest4_key": cfg.Geetest4Key,
},
}
_ = c.ServeJSON()
}
// GeetestCheck 极验配置自检:判断服务器能否访问极验、captcha_key 是否与 captcha_id 匹配
// GET /platform/geetestCheck
func (c *PlatformLoginVerifyController) GeetestCheck() {
diag := authsvc.DiagnoseGeetest4()
code := 200
if ok, _ := diag["ok"].(bool); !ok {
code = 500
}
c.Data["json"] = map[string]interface{}{
"code": code,
"msg": diag["msg"],
"data": diag,
}
_ = c.ServeJSON()
}
// SaveLoginVerifyInfos 保存登录验证配置
// POST /platform/saveloginVerifyInfos
func (c *PlatformLoginVerifyController) SaveLoginVerifyInfos() {
var p loginVerifyPayload
raw, _ := io.ReadAll(c.Ctx.Request.Body)
if err := json.Unmarshal(raw, &p); err != nil {
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "参数错误"}
_ = c.ServeJSON()
return
}
verifyType := normalizeVerifyType(p.VerifyType)
openVerifyEnabled := int8(1)
if p.OpenVerifyEnabled != nil {
openVerifyEnabled = *p.OpenVerifyEnabled
}
if verifyType == "geetest" {
if p.Geetest4ID == nil || strings.TrimSpace(*p.Geetest4ID) == "" {
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "geetest4_id 不能为空"}
_ = c.ServeJSON()
return
}
if p.Geetest4Key == nil || strings.TrimSpace(*p.Geetest4Key) == "" {
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "geetest4_key 不能为空"}
_ = c.ServeJSON()
return
}
}
err := models.SavePlatformLoginVerify(&models.PlatformLoginVerify{
OpenVerifyEnabled: openVerifyEnabled,
VerifyType: verifyType,
Geetest3ID: p.Geetest3ID,
Geetest3Key: p.Geetest3Key,
Geetest4ID: p.Geetest4ID,
Geetest4Key: p.Geetest4Key,
})
if err != nil {
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "保存失败"}
_ = c.ServeJSON()
return
}
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "保存成功"}
_ = c.ServeJSON()
}