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

323 lines
8.8 KiB
Go

package controllers
import (
"encoding/json"
"io"
"strings"
"server/models"
"server/pkg/jwtutil"
"server/services"
beego "github.com/beego/beego/v2/server/web"
)
type backendAuthLoginRequest struct {
TenantName string `json:"tenant_name"`
Account string `json:"account"`
Password string `json:"password"`
Code string `json:"code"`
// 极验4验证参数
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"`
}
// BackendAuthController backend 端认证控制器
type BackendAuthController struct {
beego.Controller
}
func (c *BackendAuthController) serveJSON(data map[string]interface{}) {
c.Data["json"] = data
_ = c.ServeJSON()
}
// LoginBackend backend 登录(需要租户)
func (c *BackendAuthController) LoginBackend() {
var req backendAuthLoginRequest
body := c.Ctx.Input.RequestBody
if len(body) == 0 {
var err error
body, err = io.ReadAll(c.Ctx.Request.Body)
if err != nil {
c.serveJSON(map[string]interface{}{"code": 400, "msg": "参数错误"})
return
}
}
if len(body) == 0 {
c.serveJSON(map[string]interface{}{"code": 400, "msg": "参数错误"})
return
}
if err := json.Unmarshal(body, &req); err != nil {
c.serveJSON(map[string]interface{}{"code": 400, "msg": "参数错误"})
return
}
req.TenantName = strings.TrimSpace(req.TenantName)
req.Account = strings.TrimSpace(req.Account)
req.Password = strings.TrimSpace(req.Password)
if req.TenantName == "" || req.Account == "" || req.Password == "" {
c.serveJSON(map[string]interface{}{"code": 400, "msg": "租户名称、用户名或密码不能为空"})
return
}
cfg, _ := models.GetPlatformLoginVerify()
if cfg.OpenVerifyEnabled == 1 {
if cfg.VerifyType == "geetest4" {
if req.LotNumber == "" || req.PassToken == "" || req.GenTime == "" || req.CaptchaOutput == "" {
c.serveJSON(map[string]interface{}{"code": 400, "msg": "请完成人机验证"})
return
}
// TODO: 集成极验4服务端 SDK 后在这里进行二次校验
} else if cfg.VerifyType == "geetest3" {
if req.CaptchaOutput == "" {
c.serveJSON(map[string]interface{}{"code": 400, "msg": "请完成人机验证"})
return
}
// TODO: 集成极验3服务端 SDK 后在这里进行二次校验
} else if cfg.VerifyType == "sms" || cfg.VerifyType == "email" {
if strings.TrimSpace(req.Code) == "" {
c.serveJSON(map[string]interface{}{"code": 400, "msg": "请输入验证码"})
return
}
if err := services.VerifyBackendLoginCode(req.TenantName, req.Account, cfg.VerifyType, req.Code); err != nil {
c.serveJSON(map[string]interface{}{"code": 400, "msg": err.Error()})
return
}
}
}
token, loginUser, err := services.BackendLogin(req.TenantName, req.Account, req.Password)
if err != nil {
c.serveJSON(map[string]interface{}{"code": 401, "msg": err.Error()})
return
}
c.serveJSON(map[string]interface{}{
"code": 200,
"msg": "登录成功",
"data": map[string]interface{}{
"token": token,
"user": map[string]interface{}{
"id": loginUser.ID,
"account": loginUser.Account,
"name": loginUser.Name,
"tid": loginUser.Tid,
"rid": loginUser.Rid,
"avatar": loginUser.Avatar,
"role_name": loginUser.RoleName,
},
},
})
}
// GetCurrentUser 当前登录 backend 用户信息,需 Bearer Token
func (c *BackendAuthController) GetCurrentUser() {
authHeader := c.Ctx.Request.Header.Get("Authorization")
if authHeader == "" {
c.serveJSON(map[string]interface{}{"code": 401, "msg": "未登录"})
return
}
authParts := strings.SplitN(authHeader, " ", 2)
if len(authParts) != 2 || authParts[0] != "Bearer" {
c.serveJSON(map[string]interface{}{"code": 401, "msg": "认证信息格式错误"})
return
}
claims, err := jwtutil.ParseToken(authParts[1])
if err != nil {
c.serveJSON(map[string]interface{}{"code": 401, "msg": "无效的token"})
return
}
if claims.UserType != "backend" {
c.serveJSON(map[string]interface{}{"code": 403, "msg": "无权访问"})
return
}
var tenantUser models.SystemTenantUser
err = models.Orm.QueryTable(new(models.SystemTenantUser)).
Filter("uid", claims.UserID).
Filter("tid", claims.TenantId).
One(&tenantUser)
if err != nil {
c.serveJSON(map[string]interface{}{"code": 401, "msg": "用户不存在"})
return
}
if tenantUser.Status == 0 {
c.serveJSON(map[string]interface{}{"code": 401, "msg": "账号已禁用"})
return
}
account := ""
if tenantUser.Account != nil {
account = strings.TrimSpace(*tenantUser.Account)
}
name := ""
if tenantUser.Name != nil {
name = strings.TrimSpace(*tenantUser.Name)
}
c.serveJSON(map[string]interface{}{
"code": 200,
"msg": "success",
"data": map[string]interface{}{
"id": tenantUser.Uid,
"account": account,
"name": name,
"tid": tenantUser.Tid,
"rid": 0,
"avatar": "",
"role_name": "",
},
})
}
// SendLoginCode 发送 backend 登录验证码
func (c *BackendAuthController) SendLoginCode() {
var req struct {
Account string `json:"account"`
TenantName string `json:"tenant_name"`
Channel string `json:"channel"`
}
body := c.Ctx.Input.RequestBody
if len(body) == 0 {
var err error
body, err = io.ReadAll(c.Ctx.Request.Body)
if err != nil {
c.serveJSON(map[string]interface{}{"code": 400, "msg": "参数错误"})
return
}
}
if err := json.Unmarshal(body, &req); err != nil {
c.serveJSON(map[string]interface{}{"code": 400, "msg": "参数错误"})
return
}
cfg, _ := models.GetPlatformLoginVerify()
if cfg.OpenVerifyEnabled != 1 {
c.serveJSON(map[string]interface{}{"code": 400, "msg": "当前未开启验证"})
return
}
channel := strings.TrimSpace(req.Channel)
if channel == "" {
channel = cfg.VerifyType
}
if channel != "sms" && channel != "email" {
c.serveJSON(map[string]interface{}{"code": 400, "msg": "仅支持短信/邮箱验证码"})
return
}
if err := services.SendBackendLoginCode(req.TenantName, req.Account, channel); err != nil {
c.serveJSON(map[string]interface{}{"code": 400, "msg": err.Error()})
return
}
c.serveJSON(map[string]interface{}{"code": 200, "msg": "验证码已发送"})
}
// LoginBySms 手机号验证码登录(占位实现)
func (c *BackendAuthController) LoginBySms() {
c.serveJSON(map[string]interface{}{
"code": 501,
"msg": "手机号验证码登录暂未实现",
})
}
// Logout backend 退出登录(当前为无状态直接返回成功)
func (c *BackendAuthController) Logout() {
c.serveJSON(map[string]interface{}{
"code": 200,
"msg": "退出成功",
})
}
// GetGeetest3Infos 获取 backend 极验3.0配置
func (c *BackendAuthController) GetGeetest3Infos() {
cfg, _ := models.GetPlatformLoginVerify()
if cfg.Geetest3ID == nil || cfg.Geetest3Key == nil {
c.serveJSON(map[string]interface{}{"code": 404, "msg": "未配置极验3参数"})
return
}
c.serveJSON(map[string]interface{}{
"code": 200,
"msg": "success",
"data": map[string]interface{}{
"captcha_id": *cfg.Geetest3ID,
"captcha_key": *cfg.Geetest3Key,
},
})
}
// GetGeetest4Infos 获取 backend 极验4.0配置
func (c *BackendAuthController) GetGeetest4Infos() {
cfg, _ := models.GetPlatformLoginVerify()
if cfg.Geetest4ID == nil || cfg.Geetest4Key == nil {
c.serveJSON(map[string]interface{}{"code": 404, "msg": "未配置极验4参数"})
return
}
c.serveJSON(map[string]interface{}{
"code": 200,
"msg": "success",
"data": map[string]interface{}{
"captcha_id": *cfg.Geetest4ID,
"captcha_key": *cfg.Geetest4Key,
},
})
}
// GetOpenVerify 判断是否开启 backend 登录验证
func (c *BackendAuthController) GetOpenVerify() {
cfg, _ := models.GetPlatformLoginVerify()
openVerify := "0"
if cfg.OpenVerifyEnabled == 1 {
openVerify = "1"
}
c.serveJSON(map[string]interface{}{
"code": 200,
"msg": "ok",
"data": []map[string]string{
{
"label": "openVerify",
"value": openVerify,
},
{
"label": "verifyType",
"value": cfg.VerifyType,
},
},
})
}
// Register 注册(占位实现)
func (c *BackendAuthController) Register() {
c.serveJSON(map[string]interface{}{
"code": 501,
"msg": "注册暂未实现",
})
}
// SendRegisterCode 发送注册验证码(占位实现)
func (c *BackendAuthController) SendRegisterCode() {
c.serveJSON(map[string]interface{}{
"code": 501,
"msg": "发送注册验证码暂未实现",
})
}
// ResetPassword 忘记密码重置(占位实现)
func (c *BackendAuthController) ResetPassword() {
c.serveJSON(map[string]interface{}{
"code": 501,
"msg": "重置密码暂未实现",
})
}
// SendResetCode 发送找回密码验证码(占位实现)
func (c *BackendAuthController) SendResetCode() {
c.serveJSON(map[string]interface{}{
"code": 501,
"msg": "发送找回密码验证码暂未实现",
})
}