jwt.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. package gauth
  2. import (
  3. "errors"
  4. "fmt"
  5. "net/http"
  6. "strconv"
  7. "strings"
  8. "time"
  9. "github.com/dgrijalva/jwt-go"
  10. "github.com/gin-gonic/gin"
  11. "github.com/happierall/l"
  12. "github.com/metarare/metarare_api/helpers"
  13. "github.com/metarare/metarare_api/helpers/terror"
  14. "github.com/metarare/metarare_api/models"
  15. "gorm.io/gorm"
  16. )
  17. const (
  18. User = iota
  19. Dev
  20. TrendersMaster
  21. TrendersAdmin
  22. BrandMaster
  23. BrandManger
  24. Influencer
  25. )
  26. func ObtainJWTKey() string {
  27. vv := helpers.LoadEnvs()
  28. v := vv.GetString("jwt.jwt_secret")
  29. if strings.Compare(v, "") != 0 {
  30. return v
  31. } else {
  32. l.Error("There is no JWTKey ")
  33. return ""
  34. }
  35. }
  36. // NOTE x GetCurrentUserID가 return type이 string이라서 int64로 하나 생성
  37. func GetCurrentUserIDToInt64(c *gin.Context) (uint64, error) {
  38. s_userID, err := GetCurrentUserID(c)
  39. if err != nil {
  40. return 0, err
  41. }
  42. n_userID, err := strconv.ParseUint(s_userID, 10, 64)
  43. if err != nil {
  44. return 0, err
  45. }
  46. return n_userID, err
  47. }
  48. func GetCurrentUserID(c *gin.Context) (string, error) {
  49. return GetCustomClaim(c, "user_id")
  50. }
  51. type AdminInfo struct {
  52. AdminID uint64 `json:"admin_id,omitempty"`
  53. Permission models.AdminPermission `json:"permission,omitempty"`
  54. }
  55. // // NOTE x 어드민에대한 정보 확인
  56. func ConfirmAdminInfo(c *gin.Context, db *gorm.DB) (models.Admin, error) {
  57. admin := models.Admin{}
  58. adminID, err := GetCurrentUserIDToInt64(c)
  59. if err != nil || adminID == 0 {
  60. return admin, err
  61. }
  62. if err := db.Where("id = ?", adminID).Preload("AdminPermission").Find(&admin).Error; err != nil {
  63. return admin, err
  64. } else if admin.ID == 0 {
  65. return admin, errors.New("not found recored")
  66. }
  67. return admin, nil
  68. }
  69. func GetCustomClaim(c *gin.Context, claimName string) (string, error) {
  70. claims, err := ValidateToken(c)
  71. if err != nil {
  72. l.Error(err)
  73. // c.AbortWithStatus(http.StatusUnauthorized)
  74. return "", err
  75. }
  76. encrpytedClaim, isValidClaim := claims[Pack(claimName)].(string)
  77. // NOTE claims에서 claimName이 존재하지 않을때
  78. if !isValidClaim {
  79. errMsg := "invalid claimName"
  80. l.Error(errMsg)
  81. return "", errors.New(errMsg)
  82. }
  83. value := UnPack(encrpytedClaim)
  84. // l.Log("[ExtractCustomCliam] revert data :", value)
  85. return value, nil
  86. }
  87. func ValidateToken(c *gin.Context) (jwt.MapClaims, error) {
  88. accessToken := c.GetHeader("Authorization")
  89. // l.Log("Received AuthToken ", accessToken)
  90. splitedToken := strings.Split(accessToken, " ")
  91. if strings.Compare(accessToken, "") == 0 ||
  92. len(splitedToken) != 2 || strings.Compare(splitedToken[0], "Bearer") != 0 {
  93. //err := fmt.Errorf("Unauthrized !!! Request header's accessToken :[", accessToken, "]")
  94. err := terror.NewErrorNoAccessToken().SetDescriptor(fmt.Sprintf("accessToken :%s", accessToken))
  95. l.Error(err)
  96. return jwt.MapClaims{}, err
  97. }
  98. // l.Log("[ExtractCustomCliam] SplitedToken (%s)", splitedToken[1])
  99. token, err := jwt.Parse(splitedToken[1], func(token *jwt.Token) (interface{}, error) {
  100. if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
  101. err := fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
  102. l.Error(err)
  103. return jwt.MapClaims{}, err
  104. }
  105. return []byte(ObtainJWTKey()), nil
  106. })
  107. if err != nil {
  108. l.Error(err)
  109. // c.AbortWithStatus(http.StatusUnauthorized)
  110. return jwt.MapClaims{}, err
  111. }
  112. claims, ok := token.Claims.(jwt.MapClaims)
  113. if ok && !token.Valid {
  114. l.Errorf("Token is not valid")
  115. // c.AbortWithStatus(http.StatusUnauthorized)
  116. return jwt.MapClaims{}, err
  117. }
  118. exp := claims["exp"].(string)
  119. expAt, _ := time.Parse(time.RFC3339, exp)
  120. if expAt.Before(time.Now()) {
  121. l.Error("Expired JWT token")
  122. // c.AbortWithStatus(http.StatusUnauthorized)
  123. return jwt.MapClaims{}, terror.NewErrorTokenExpired()
  124. }
  125. return claims, nil
  126. }
  127. //SECTION verification of password reset token
  128. func ValidateResetToken(c *gin.Context, resetToken string) (jwt.MapClaims, error) {
  129. token, err := jwt.Parse(resetToken, func(token *jwt.Token) (interface{}, error) {
  130. if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
  131. err := errors.New("unexpected signing method")
  132. l.Error(err)
  133. return jwt.MapClaims{}, err
  134. }
  135. return []byte(ObtainJWTKey()), nil
  136. })
  137. if err != nil {
  138. l.Error(err)
  139. return jwt.MapClaims{}, err
  140. }
  141. claims, ok := token.Claims.(jwt.MapClaims)
  142. if ok && !token.Valid {
  143. l.Errorf("Token is not valid")
  144. return jwt.MapClaims{}, err
  145. }
  146. exp := claims["exp"].(string)
  147. expAt, _ := time.Parse(time.RFC3339, exp)
  148. if expAt.Before(time.Now()) {
  149. l.Error("Expired JWT token")
  150. return jwt.MapClaims{}, terror.NewErrorTokenExpired()
  151. }
  152. return claims, nil
  153. }
  154. func GetRegisteredClaim(c *gin.Context, claimName string) (interface{}, error) {
  155. claims, err := ValidateToken(c)
  156. if err != nil {
  157. l.Error(err)
  158. // c.AbortWithStatus(http.StatusUnauthorized)
  159. return "", err
  160. }
  161. registeredClaim := claims[claimName].(interface{})
  162. // l.Log(registeredClaim)
  163. //l.Log("[ExtractRegisterdCliam] data :", registeredClaim)
  164. return registeredClaim, nil
  165. }
  166. func GetCurrentUserType(c *gin.Context) (string, error) {
  167. aud, err := GetRegisteredClaim(c, "aud")
  168. if err != nil {
  169. l.Error(err)
  170. // c.AbortWithStatus(http.StatusUnauthorized)
  171. return "", err
  172. }
  173. aud = int(aud.(float64))
  174. var userType string
  175. // 7renders
  176. if aud == TrendersMaster || aud == TrendersAdmin {
  177. userType = "7renders"
  178. // brand
  179. } else if aud == BrandMaster || aud == BrandManger {
  180. userType = "brand"
  181. // influecner
  182. } else if aud == Influencer {
  183. userType = "influencer"
  184. // dev
  185. } else if aud == Dev {
  186. userType = "dev"
  187. // guest
  188. } else if aud == User {
  189. userType = "guest"
  190. } else {
  191. l.Error("Unkown auth_type(securityLevel)")
  192. c.String(http.StatusOK, "Unknown user")
  193. return "", err
  194. }
  195. return userType, nil
  196. }