go-platform/controllers/backend_login_verify.go
2026-06-02 21:15:13 +08:00

250 lines
6.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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()
}