local_auth.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package controllers
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "shudao-chat-go/models"
  6. "shudao-chat-go/utils"
  7. "github.com/beego/beego/v2/server/web"
  8. "golang.org/x/crypto/bcrypt"
  9. )
  10. // LocalAuthController 本地认证控制器
  11. type LocalAuthController struct {
  12. web.Controller
  13. }
  14. // LocalLoginRequest 本地登录请求结构
  15. type LocalLoginRequest struct {
  16. Username string `json:"username"`
  17. Password string `json:"password"`
  18. }
  19. // LocalLoginResponse 本地登录响应结构
  20. type LocalLoginResponse struct {
  21. StatusCode int `json:"statusCode"`
  22. Msg string `json:"msg"`
  23. Token string `json:"token,omitempty"`
  24. UserInfo *LocalUserInfo `json:"userInfo,omitempty"`
  25. }
  26. // LocalUserInfo 本地用户信息
  27. type LocalUserInfo struct {
  28. ID uint `json:"id"`
  29. Username string `json:"username"`
  30. Nickname string `json:"nickname"`
  31. Role string `json:"role"`
  32. Email string `json:"email"`
  33. }
  34. // LocalLogin 本地登录接口
  35. func (c *LocalAuthController) LocalLogin() {
  36. // 检查是否启用本地登录
  37. enableLocalLogin, err := web.AppConfig.Bool("enable_local_login")
  38. if err != nil || !enableLocalLogin {
  39. c.Data["json"] = LocalLoginResponse{
  40. StatusCode: 403,
  41. Msg: "本地登录功能未启用",
  42. }
  43. c.ServeJSON()
  44. return
  45. }
  46. // 解析请求体
  47. var req LocalLoginRequest
  48. if err := json.Unmarshal(c.Ctx.Input.RequestBody, &req); err != nil {
  49. c.Data["json"] = LocalLoginResponse{
  50. StatusCode: 400,
  51. Msg: "请求参数解析失败",
  52. }
  53. c.ServeJSON()
  54. return
  55. }
  56. // 验证必填字段
  57. if req.Username == "" || req.Password == "" {
  58. c.Data["json"] = LocalLoginResponse{
  59. StatusCode: 400,
  60. Msg: "用户名和密码不能为空",
  61. }
  62. c.ServeJSON()
  63. return
  64. }
  65. fmt.Printf("🔐 [本地登录] 用户 %s 尝试登录\n", req.Username)
  66. // 查询用户
  67. var user models.User
  68. result := models.DB.Where("username = ? AND is_deleted = 0", req.Username).First(&user)
  69. if result.Error != nil {
  70. fmt.Printf("❌ [本地登录] 用户不存在: %s\n", req.Username)
  71. c.Data["json"] = LocalLoginResponse{
  72. StatusCode: 401,
  73. Msg: "用户名或密码错误",
  74. }
  75. c.ServeJSON()
  76. return
  77. }
  78. // 检查用户状态
  79. if user.Status != 1 {
  80. fmt.Printf("❌ [本地登录] 用户已被禁用: %s\n", req.Username)
  81. c.Data["json"] = LocalLoginResponse{
  82. StatusCode: 403,
  83. Msg: "用户已被禁用",
  84. }
  85. c.ServeJSON()
  86. return
  87. }
  88. // 验证密码
  89. err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password))
  90. if err != nil {
  91. fmt.Printf("❌ [本地登录] 密码错误: %s\n", req.Username)
  92. c.Data["json"] = LocalLoginResponse{
  93. StatusCode: 401,
  94. Msg: "用户名或密码错误",
  95. }
  96. c.ServeJSON()
  97. return
  98. }
  99. // 生成本地token
  100. token, err := utils.GenerateLocalToken(user.ID, user.Username, user.Role)
  101. if err != nil {
  102. fmt.Printf("❌ [本地登录] 生成token失败: %v\n", err)
  103. c.Data["json"] = LocalLoginResponse{
  104. StatusCode: 500,
  105. Msg: "生成token失败",
  106. }
  107. c.ServeJSON()
  108. return
  109. }
  110. fmt.Printf("✅ [本地登录] 用户 %s 登录成功\n", req.Username)
  111. // 返回成功响应
  112. c.Data["json"] = LocalLoginResponse{
  113. StatusCode: 200,
  114. Msg: "登录成功",
  115. Token: token,
  116. UserInfo: &LocalUserInfo{
  117. ID: user.ID,
  118. Username: user.Username,
  119. Nickname: user.Nickname,
  120. Role: user.Role,
  121. Email: user.Email,
  122. },
  123. }
  124. c.ServeJSON()
  125. }