v2版本
This commit is contained in:
225
internal/api/auth_handler.go
Normal file
225
internal/api/auth_handler.go
Normal file
@@ -0,0 +1,225 @@
|
||||
/**
|
||||
* 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 := 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,
|
||||
}, "登录成功")
|
||||
}
|
||||
|
||||
// getClientIP 获取客户端IP
|
||||
func getClientIP(c *gin.Context) string {
|
||||
// 优先从X-Forwarded-For获取
|
||||
ip := c.GetHeader("X-Forwarded-For")
|
||||
if ip != "" {
|
||||
return ip
|
||||
}
|
||||
|
||||
// 从X-Real-IP获取
|
||||
ip = c.GetHeader("X-Real-IP")
|
||||
if ip != "" {
|
||||
return ip
|
||||
}
|
||||
|
||||
// 从RemoteAddr获取
|
||||
return c.ClientIP()
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, // 仅开发环境,生产环境应移除
|
||||
}, "验证码已发送")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user