go-platform/controllers/platform_auth.go

426 lines
12 KiB
Go
Raw Permalink 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"
"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()
}