adminLoginLogic.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package pub
  2. import (
  3. "context"
  4. "crypto/subtle"
  5. "errors"
  6. "time"
  7. "perms-system-server/internal/consts"
  8. authHelper "perms-system-server/internal/logic/auth"
  9. "perms-system-server/internal/model/user"
  10. "perms-system-server/internal/response"
  11. "perms-system-server/internal/svc"
  12. "perms-system-server/internal/types"
  13. "github.com/zeromicro/go-zero/core/limit"
  14. "github.com/zeromicro/go-zero/core/logx"
  15. "golang.org/x/crypto/bcrypt"
  16. )
  17. type AdminLoginLogic struct {
  18. logx.Logger
  19. ctx context.Context
  20. svcCtx *svc.ServiceContext
  21. }
  22. func NewAdminLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminLoginLogic {
  23. return &AdminLoginLogic{
  24. Logger: logx.WithContext(ctx),
  25. ctx: ctx,
  26. svcCtx: svcCtx,
  27. }
  28. }
  29. // AdminLogin 管理后台登录。仅限超级管理员通过 managementKey + 用户名密码登录管理后台,返回 JWT 令牌对。
  30. func (l *AdminLoginLogic) AdminLogin(req *types.AdminLoginReq) (resp *types.LoginResp, err error) {
  31. if subtle.ConstantTimeCompare([]byte(req.ManagementKey), []byte(l.svcCtx.Config.Auth.ManagementKey)) != 1 {
  32. return nil, response.ErrUnauthorized("managementKey无效")
  33. }
  34. if l.svcCtx.UsernameLoginLimit != nil {
  35. code, _ := l.svcCtx.UsernameLoginLimit.Take(req.Username)
  36. if code == limit.OverQuota {
  37. return nil, response.NewCodeError(429, "该账号登录尝试过于频繁,请5分钟后再试")
  38. }
  39. }
  40. u, err := l.svcCtx.SysUserModel.FindOneByUsername(l.ctx, req.Username)
  41. if err != nil {
  42. if errors.Is(err, user.ErrNotFound) {
  43. return nil, response.ErrUnauthorized("用户名或密码错误")
  44. }
  45. return nil, err
  46. }
  47. if u.Status != consts.StatusEnabled {
  48. return nil, response.ErrForbidden("账号已被冻结")
  49. }
  50. if err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(req.Password)); err != nil {
  51. return nil, response.ErrUnauthorized("用户名或密码错误")
  52. }
  53. if u.IsSuperAdmin != consts.IsSuperAdminYes {
  54. return nil, response.ErrForbidden("仅超级管理员可通过管理后台登录")
  55. }
  56. ud := l.svcCtx.UserDetailsLoader.Load(l.ctx, u.Id, "")
  57. accessToken, err := authHelper.GenerateAccessToken(
  58. l.svcCtx.Config.Auth.AccessSecret,
  59. l.svcCtx.Config.Auth.AccessExpire,
  60. ud.UserId, ud.Username, ud.ProductCode, ud.MemberType, ud.TokenVersion,
  61. )
  62. if err != nil {
  63. return nil, err
  64. }
  65. refreshToken, err := authHelper.GenerateRefreshToken(
  66. l.svcCtx.Config.Auth.RefreshSecret,
  67. l.svcCtx.Config.Auth.RefreshExpire,
  68. ud.UserId, ud.ProductCode, ud.TokenVersion,
  69. )
  70. if err != nil {
  71. return nil, err
  72. }
  73. return &types.LoginResp{
  74. AccessToken: accessToken,
  75. RefreshToken: refreshToken,
  76. Expires: time.Now().Unix() + l.svcCtx.Config.Auth.AccessExpire,
  77. UserInfo: types.UserInfo{
  78. UserId: ud.UserId,
  79. Username: ud.Username,
  80. Nickname: ud.Nickname,
  81. Avatar: ud.Avatar,
  82. Email: ud.Email,
  83. Phone: ud.Phone,
  84. IsSuperAdmin: ud.IsSuperAdminRaw,
  85. MustChangePassword: ud.MustChangePwdRaw,
  86. MemberType: ud.MemberType,
  87. Perms: ud.Perms,
  88. },
  89. }, nil
  90. }