auth.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package auth
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/sirupsen/logrus"
  6. "go-micro.dev/v4/auth"
  7. "go-micro.dev/v4/metadata"
  8. "sghgogs.com/micro/common"
  9. "sghgogs.com/micro/common/errorcode"
  10. "sghgogs.com/micro/shopping-service/domain/service"
  11. pb "sghgogs.com/micro/shopping-service/proto"
  12. "sghgogs.com/micro/shopping-service/utils/authutil"
  13. "strconv"
  14. "strings"
  15. "time"
  16. )
  17. type Auth struct {
  18. Service service.IService
  19. Namespace string
  20. }
  21. func (svc *Auth) Login(ctx context.Context, query *pb.LoginRequest, rsp *pb.LoginResponse) error {
  22. login, GroupID, err := svc.Service.Login(query)
  23. if err != nil {
  24. return err
  25. }
  26. md := map[string]string{}
  27. md["username"] = login.Username
  28. md["user_id"] = fmt.Sprintf("%d", login.Id)
  29. md["phone_number"] = login.PhoneNumber
  30. md["code"] = query.Code
  31. md["group_id"] = fmt.Sprintf("%d", GroupID)
  32. var roles []string
  33. for _, role := range login.Roles {
  34. roles = append(roles, strings.ToLower(role.Key))
  35. }
  36. expiry := time.Second * time.Duration(72*3600)
  37. md["timestamp"] = fmt.Sprintf("%d", 72*3600)
  38. md["expiry"] = fmt.Sprintf("%d", expiry)
  39. token, err := authutil.JWTAuthService.GenerateToken(login.Id, "system", "user", login.PhoneNumber, roles, md)
  40. if err != nil {
  41. return errorcode.BadRequest(svc.Namespace, common.ErrorMessage[common.FailedToGenerateTokenErrorCode])
  42. }
  43. a, err := authutil.JWTAuthService.Token(login.Id, token.Secret, expiry)
  44. if err != nil {
  45. return errorcode.BadRequest(svc.Namespace, common.ErrorMessage[common.FailedToGenerateTokenErrorCode])
  46. }
  47. if err = authutil.JWTAuthService.StoreToken(ctx, login.Id, login.Username, a.AccessToken); err != nil {
  48. return errorcode.BadRequest(svc.Namespace, common.ErrorMessage[common.FailedToStoreTokenErrorCode])
  49. }
  50. rsp.Data = login
  51. rsp.Token = a.AccessToken
  52. return nil
  53. }
  54. func (svc *Auth) Logout(ctx context.Context, request *pb.LogoutRequest, rsp *pb.LogoutResponse) error {
  55. md, b := metadata.FromContext(ctx)
  56. if !b {
  57. return errorcode.Unauthorized(svc.Namespace, common.ErrorMessage[common.UnauthorizedErrorCode])
  58. }
  59. authHeader, ok := md["Authorization"]
  60. if !ok || !strings.HasPrefix(authHeader, auth.BearerScheme) {
  61. logrus.Error("no auth token provided")
  62. return errorcode.Unauthorized(svc.Namespace, common.ErrorMessage[common.UnauthorizedErrorCode])
  63. }
  64. // Extract auth token.
  65. token := strings.TrimPrefix(authHeader, auth.BearerScheme)
  66. token = strings.TrimSpace(token)
  67. if err := authutil.JWTAuthService.Blacklist(token); err != nil {
  68. return errorcode.Unauthorized(svc.Namespace, common.ErrorMessage[common.FailedRedisInternalServerErrorCode])
  69. }
  70. return nil
  71. }
  72. func (svc *Auth) Profile(ctx context.Context, request *pb.ProfileRequest, rsp *pb.ProfileResponse) error {
  73. md, b := metadata.FromContext(ctx)
  74. if !b {
  75. return errorcode.Unauthorized(svc.Namespace, common.ErrorMessage[common.UnauthorizedErrorCode])
  76. }
  77. authHeader, ok := md["Authorization"]
  78. if !ok || !strings.HasPrefix(authHeader, auth.BearerScheme) {
  79. logrus.Error("no auth token provided")
  80. return errorcode.Unauthorized(svc.Namespace, common.ErrorMessage[common.UnauthorizedErrorCode])
  81. }
  82. // Extract auth token.
  83. token := strings.TrimPrefix(authHeader, auth.BearerScheme)
  84. token = strings.TrimSpace(token)
  85. inspect, errE := authutil.JWTAuthService.Inspect(token)
  86. if errE != nil {
  87. return errorcode.Unauthorized(svc.Namespace, common.ErrorMessage[common.TokenInvalidErrorCode])
  88. }
  89. if value, isOk := inspect.Metadata["user_id"]; isOk {
  90. userID, _ := strconv.ParseInt(value, 10, 64)
  91. groupID, _ := strconv.ParseInt(inspect.Metadata["group_id"], 10, 64)
  92. if profile, err := svc.Service.Profile(groupID, userID); err != nil {
  93. return err
  94. } else {
  95. rsp.Data = profile
  96. }
  97. }
  98. return nil
  99. }