207 lines
4.4 KiB
Go
207 lines
4.4 KiB
Go
/**
|
||
* package api
|
||
* 作用:认证相关API处理器
|
||
*/
|
||
package api
|
||
|
||
import (
|
||
"xk-websocket-v2/internal/model"
|
||
"xk-websocket-v2/internal/service"
|
||
"xk-websocket-v2/internal/utils"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
/**
|
||
* LoginHandler
|
||
* 功能:用户登录
|
||
* 路径:POST /api/login
|
||
*/
|
||
func LoginHandler(c *gin.Context) {
|
||
var req model.LoginReq
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
utils.BadRequest(c, "参数错误: "+err.Error())
|
||
return
|
||
}
|
||
|
||
// 获取客户端IP
|
||
ip := utils.GetClientIP(c)
|
||
|
||
// 调用认证服务登录
|
||
user, err := service.AuthSvc.Login(req.Account, req.Password)
|
||
if err != nil {
|
||
// 记录登录失败日志
|
||
service.LoginLogSvc.LogLogin(req.Account, "0", ip, false)
|
||
utils.Unauthorized(c, err.Error())
|
||
return
|
||
}
|
||
|
||
// 生成Token
|
||
token, err := utils.GenerateToken(user.ID)
|
||
if err != nil {
|
||
// 记录登录失败日志
|
||
service.LoginLogSvc.LogLogin(req.Account, "0", ip, false)
|
||
utils.InternalError(c, "生成Token失败")
|
||
return
|
||
}
|
||
|
||
// 清除密码字段
|
||
user.Password = ""
|
||
|
||
// 记录登录成功日志
|
||
service.LoginLogSvc.LogLogin(req.Account, user.ID, ip, true)
|
||
|
||
utils.SuccessWithData(c, model.LoginResponse{
|
||
Token: token,
|
||
User: *user,
|
||
}, "登录成功")
|
||
}
|
||
|
||
/**
|
||
* RegisterHandler
|
||
* 功能:用户注册
|
||
* 路径:POST /api/register
|
||
*/
|
||
func RegisterHandler(c *gin.Context) {
|
||
var req model.RegisterReq
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
utils.BadRequest(c, "参数错误: "+err.Error())
|
||
return
|
||
}
|
||
|
||
// 如果提供了验证码,验证验证码
|
||
if req.Code != "" {
|
||
// 根据邮箱或手机号确定类型
|
||
codeType := "email"
|
||
if len(req.Phone) > 0 {
|
||
codeType = "sms"
|
||
}
|
||
target := req.Email
|
||
if codeType == "sms" {
|
||
target = req.Phone
|
||
}
|
||
|
||
valid, err := service.AuthSvc.VerifyCode(target, req.Code, codeType)
|
||
if err != nil || !valid {
|
||
utils.BadRequest(c, "验证码无效或已过期")
|
||
return
|
||
}
|
||
}
|
||
|
||
// 调用认证服务注册
|
||
user, err := service.AuthSvc.Register(&req)
|
||
if err != nil {
|
||
utils.BadRequest(c, err.Error())
|
||
return
|
||
}
|
||
|
||
// 生成Token
|
||
token, err := utils.GenerateToken(user.ID)
|
||
if err != nil {
|
||
utils.InternalError(c, "生成Token失败")
|
||
return
|
||
}
|
||
|
||
utils.SuccessWithData(c, model.RegisterResponse{
|
||
Token: token,
|
||
User: *user,
|
||
}, "注册成功")
|
||
}
|
||
|
||
/**
|
||
* LogoutHandler
|
||
* 功能:用户登出(可选,前端清除token)
|
||
* 路径:POST /api/logout
|
||
*/
|
||
func LogoutHandler(c *gin.Context) {
|
||
// 登出主要是前端清除token,后端可以记录日志或清除session
|
||
utils.Success(c, "登出成功")
|
||
}
|
||
|
||
/**
|
||
* CheckTokenHandler
|
||
* 功能:检查Token有效性
|
||
* 路径:GET /api/check-token
|
||
*/
|
||
func CheckTokenHandler(c *gin.Context) {
|
||
token := c.GetHeader("Authorization")
|
||
if token == "" {
|
||
utils.Unauthorized(c, "缺少Token")
|
||
return
|
||
}
|
||
|
||
// 移除 "Bearer " 前缀(如果存在)
|
||
if len(token) > 7 && token[:7] == "Bearer " {
|
||
token = token[7:]
|
||
}
|
||
|
||
userID, err := utils.ValidateToken(token)
|
||
if err != nil {
|
||
utils.Unauthorized(c, "Token无效或已过期")
|
||
return
|
||
}
|
||
|
||
utils.SuccessWithData(c, gin.H{
|
||
"status": "valid",
|
||
"user_id": userID,
|
||
}, "Token有效")
|
||
}
|
||
|
||
/**
|
||
* SendEmailCodeHandler
|
||
* 功能:发送邮箱验证码
|
||
* 路径:POST /api/send-email-code
|
||
*/
|
||
func SendEmailCodeHandler(c *gin.Context) {
|
||
var req model.SendCodeReq
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
utils.BadRequest(c, "参数错误: "+err.Error())
|
||
return
|
||
}
|
||
|
||
if req.Type != "email" {
|
||
utils.BadRequest(c, "类型必须是email")
|
||
return
|
||
}
|
||
|
||
code, err := service.AuthSvc.SendEmailCode(req.Target)
|
||
if err != nil {
|
||
utils.InternalError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
// 开发环境返回验证码,生产环境不应返回
|
||
utils.SuccessWithData(c, gin.H{
|
||
"code": code, // 仅开发环境,生产环境应移除
|
||
}, "验证码已发送")
|
||
}
|
||
|
||
/**
|
||
* SendSmsCodeHandler
|
||
* 功能:发送短信验证码
|
||
* 路径:POST /api/send-sms-code
|
||
*/
|
||
func SendSmsCodeHandler(c *gin.Context) {
|
||
var req model.SendCodeReq
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
utils.BadRequest(c, "参数错误: "+err.Error())
|
||
return
|
||
}
|
||
|
||
if req.Type != "sms" {
|
||
utils.BadRequest(c, "类型必须是sms")
|
||
return
|
||
}
|
||
|
||
code, err := service.AuthSvc.SendSmsCode(req.Target)
|
||
if err != nil {
|
||
utils.InternalError(c, err.Error())
|
||
return
|
||
}
|
||
|
||
// 开发环境返回验证码,生产环境不应返回
|
||
utils.SuccessWithData(c, gin.H{
|
||
"code": code, // 仅开发环境,生产环境应移除
|
||
}, "验证码已发送")
|
||
}
|