426 lines
12 KiB
Go
426 lines
12 KiB
Go
package controllers
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"strings"
|
||
|
||
"server/models"
|
||
"server/pkg/jwtutil"
|
||
"server/services"
|
||
|
||
beego "github.com/beego/beego/v2/server/web"
|
||
)
|
||
|
||
type platformLoginRequest struct {
|
||
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"`
|
||
}
|
||
|
||
type backendLoginRequest struct {
|
||
TenantName string `json:"tenant_name"`
|
||
Account string `json:"account"`
|
||
Password string `json:"password"`
|
||
Code string `json:"code"`
|
||
}
|
||
|
||
// PlatformAuthController 平台端认证控制器
|
||
type PlatformAuthController struct {
|
||
beego.Controller
|
||
}
|
||
|
||
// LoginPlatform 平台端登录(不需要租户)
|
||
func (c *PlatformAuthController) LoginPlatform() {
|
||
var req platformLoginRequest
|
||
|
||
// 先尝试从缓存读取
|
||
body := c.Ctx.Input.RequestBody
|
||
|
||
// 如果缓存为空,直接从请求体读取
|
||
if len(body) == 0 {
|
||
var err error
|
||
body, err = io.ReadAll(c.Ctx.Request.Body)
|
||
if err != nil {
|
||
fmt.Println("读取请求体失败:", err)
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 400,
|
||
"msg": "参数错误",
|
||
}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
}
|
||
|
||
if len(body) == 0 {
|
||
fmt.Println("请求体为空")
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 400,
|
||
"msg": "参数错误",
|
||
}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
fmt.Println("登录请求体:", string(body))
|
||
|
||
if err := json.Unmarshal(body, &req); err != nil {
|
||
fmt.Println("JSON解析失败:", err, "body:", string(body))
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 400,
|
||
"msg": "参数错误: " + err.Error(),
|
||
}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
fmt.Printf("解析后的请求: %+v\n", req)
|
||
|
||
if req.Account == "" || req.Password == "" {
|
||
fmt.Println("账号或密码为空, account:", req.Account, "password:", req.Password)
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 400,
|
||
"msg": "用户名或密码不能为空",
|
||
}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
cfg, _ := models.GetPlatformLoginVerify()
|
||
if cfg.OpenVerifyEnabled == 1 {
|
||
// 极验验证
|
||
if cfg.VerifyType == "geetest4" {
|
||
if req.LotNumber == "" || req.PassToken == "" || req.GenTime == "" || req.CaptchaOutput == "" {
|
||
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "请完成人机验证"}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
// TODO: 这里应该调用极验服务端SDK验证,暂时跳过验证
|
||
// 如果需要严格验证,需要集成极验服务端SDK
|
||
} else if cfg.VerifyType == "geetest3" {
|
||
// 极验3验证
|
||
if req.CaptchaOutput == "" {
|
||
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "请完成人机验证"}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
// TODO: 这里应该调用极验服务端SDK验证,暂时跳过验证
|
||
} else if cfg.VerifyType == "sms" || cfg.VerifyType == "email" {
|
||
if strings.TrimSpace(req.Code) == "" {
|
||
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "请输入验证码"}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
if err := services.VerifyPlatformLoginCode(req.Account, cfg.VerifyType, req.Code); err != nil {
|
||
c.Data["json"] = map[string]interface{}{"code": 400, "msg": err.Error()}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
}
|
||
}
|
||
|
||
// 控制器只做 HTTP 解析与响应编排,业务逻辑放 services 层
|
||
token, loginUser, err := services.PlatformAdminLogin(req.Account, req.Password)
|
||
if err != nil {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 401,
|
||
"msg": err.Error(),
|
||
}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
c.Data["json"] = 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,
|
||
"rid": loginUser.Rid,
|
||
"avatar": loginUser.Avatar,
|
||
"role_name": loginUser.RoleName,
|
||
},
|
||
},
|
||
}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// LoginBackend backend 登录(需要租户)
|
||
func (c *PlatformAuthController) LoginBackend() {
|
||
var req backendLoginRequest
|
||
|
||
body := c.Ctx.Input.RequestBody
|
||
if len(body) == 0 {
|
||
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "参数错误"}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
if err := json.Unmarshal(body, &req); err != nil {
|
||
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "参数错误"}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
if req.TenantName == "" || req.Account == "" || req.Password == "" {
|
||
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "租户名称、用户名或密码不能为空"}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
cfg, _ := models.GetPlatformLoginVerify()
|
||
if cfg.OpenVerifyEnabled == 1 {
|
||
if cfg.VerifyType == "sms" || cfg.VerifyType == "email" {
|
||
if strings.TrimSpace(req.Code) == "" {
|
||
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "请输入验证码"}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
if err := services.VerifyBackendLoginCode(req.TenantName, req.Account, cfg.VerifyType, req.Code); err != nil {
|
||
c.Data["json"] = map[string]interface{}{"code": 400, "msg": err.Error()}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
}
|
||
}
|
||
|
||
token, loginUser, err := services.BackendLogin(req.TenantName, req.Account, req.Password)
|
||
if err != nil {
|
||
c.Data["json"] = map[string]interface{}{"code": 401, "msg": err.Error()}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
c.Data["json"] = 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,
|
||
},
|
||
},
|
||
}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// GetCurrentUser 当前登录平台用户信息(含角色名称),需 Bearer Token
|
||
func (c *PlatformAuthController) GetCurrentUser() {
|
||
authHeader := c.Ctx.Request.Header.Get("Authorization")
|
||
if authHeader == "" {
|
||
c.Data["json"] = map[string]interface{}{"code": 401, "msg": "未登录"}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
authParts := strings.SplitN(authHeader, " ", 2)
|
||
if len(authParts) != 2 || authParts[0] != "Bearer" {
|
||
c.Data["json"] = map[string]interface{}{"code": 401, "msg": "认证信息格式错误"}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
claims, err := jwtutil.ParseToken(authParts[1])
|
||
if err != nil {
|
||
c.Data["json"] = map[string]interface{}{"code": 401, "msg": "无效的token"}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
if claims.UserType != "platform" {
|
||
c.Data["json"] = map[string]interface{}{"code": 403, "msg": "无权访问"}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
loginUser, err := services.PlatformGetCurrentUser(uint64(claims.UserID))
|
||
if err != nil {
|
||
c.Data["json"] = map[string]interface{}{"code": 401, "msg": err.Error()}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": map[string]interface{}{
|
||
"id": loginUser.ID,
|
||
"account": loginUser.Account,
|
||
"name": loginUser.Name,
|
||
"rid": loginUser.Rid,
|
||
"avatar": loginUser.Avatar,
|
||
"role_name": loginUser.RoleName,
|
||
},
|
||
}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// SendLoginCode 发送登录验证码(占位实现)
|
||
func (c *PlatformAuthController) SendLoginCode() {
|
||
var req struct {
|
||
Account string `json:"account"`
|
||
TenantName string `json:"tenant_name"`
|
||
Channel string `json:"channel"`
|
||
}
|
||
body := c.Ctx.Input.RequestBody
|
||
if err := json.Unmarshal(body, &req); err != nil {
|
||
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "参数错误"}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
cfg, _ := models.GetPlatformLoginVerify()
|
||
if cfg.OpenVerifyEnabled != 1 {
|
||
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "当前未开启验证"}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
channel := strings.TrimSpace(req.Channel)
|
||
if channel == "" {
|
||
channel = cfg.VerifyType
|
||
}
|
||
if channel != "sms" && channel != "email" {
|
||
c.Data["json"] = map[string]interface{}{"code": 400, "msg": "仅支持短信/邮箱验证码"}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
path := strings.ToLower(c.Ctx.Request.URL.Path)
|
||
var sendErr error
|
||
if strings.HasPrefix(path, "/backend/") {
|
||
sendErr = services.SendBackendLoginCode(req.TenantName, req.Account, channel)
|
||
} else {
|
||
sendErr = services.SendPlatformLoginCode(req.Account, channel)
|
||
}
|
||
if sendErr != nil {
|
||
c.Data["json"] = map[string]interface{}{"code": 400, "msg": sendErr.Error()}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
c.Data["json"] = map[string]interface{}{"code": 200, "msg": "验证码已发送"}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// LoginBySms 手机号验证码登录(占位实现)
|
||
func (c *PlatformAuthController) LoginBySms() {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 501,
|
||
"msg": "手机号验证码登录暂未实现",
|
||
}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// Logout 平台退出登录(占位实现,当前为无状态直接返回成功)
|
||
func (c *PlatformAuthController) Logout() {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 200,
|
||
"msg": "退出成功",
|
||
}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// GetGeetest3Infos 获取极验3.0配置(占位实现)
|
||
func (c *PlatformAuthController) GetGeetest3Infos() {
|
||
cfg, _ := models.GetPlatformLoginVerify()
|
||
if cfg.Geetest3ID == nil || cfg.Geetest3Key == nil {
|
||
c.Data["json"] = map[string]interface{}{"code": 404, "msg": "未配置极验3参数"}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": map[string]interface{}{
|
||
"captcha_id": *cfg.Geetest3ID,
|
||
"captcha_key": *cfg.Geetest3Key,
|
||
},
|
||
}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// GetGeetest4Infos 获取极验4.0配置(占位实现)
|
||
func (c *PlatformAuthController) GetGeetest4Infos() {
|
||
cfg, _ := models.GetPlatformLoginVerify()
|
||
if cfg.Geetest4ID == nil || cfg.Geetest4Key == nil {
|
||
c.Data["json"] = map[string]interface{}{"code": 404, "msg": "未配置极验4参数"}
|
||
_ = c.ServeJSON()
|
||
return
|
||
}
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": map[string]interface{}{
|
||
"captcha_id": *cfg.Geetest4ID,
|
||
"captcha_key": *cfg.Geetest4Key,
|
||
},
|
||
}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// GetOpenVerify 判断是否开启登录验证(占位实现)
|
||
func (c *PlatformAuthController) GetOpenVerify() {
|
||
cfg, _ := models.GetPlatformLoginVerify()
|
||
openVerify := "0"
|
||
if cfg.OpenVerifyEnabled == 1 {
|
||
openVerify = "1"
|
||
}
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 200,
|
||
"msg": "ok",
|
||
"data": []map[string]string{
|
||
{
|
||
"label": "openVerify",
|
||
"value": openVerify,
|
||
},
|
||
{
|
||
"label": "verifyType",
|
||
"value": cfg.VerifyType,
|
||
},
|
||
},
|
||
}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// Register 注册(占位实现)
|
||
func (c *PlatformAuthController) Register() {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 501,
|
||
"msg": "注册暂未实现",
|
||
}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// SendRegisterCode 发送注册验证码(占位实现)
|
||
func (c *PlatformAuthController) SendRegisterCode() {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 501,
|
||
"msg": "发送注册验证码暂未实现",
|
||
}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// ResetPassword 忘记密码重置(占位实现)
|
||
func (c *PlatformAuthController) ResetPassword() {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 501,
|
||
"msg": "重置密码暂未实现",
|
||
}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// SendResetCode 发送找回密码验证码(占位实现)
|
||
func (c *PlatformAuthController) SendResetCode() {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"code": 501,
|
||
"msg": "发送找回密码验证码暂未实现",
|
||
}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|