蛋蛋星球-制度模式
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
2.9 KiB

  1. package jwt
  2. import (
  3. "encoding/json"
  4. "errors"
  5. )
  6. // Claims type that uses the map[string]any for JSON decoding
  7. // This is the default claims type if you don't supply one
  8. type MapClaims map[string]any
  9. // VerifyAudience Compares the aud claim against cmp.
  10. // If required is false, this method will return true if the value matches or is unset
  11. func (m MapClaims) VerifyAudience(cmp string, req bool) bool {
  12. var aud []string
  13. switch v := m["aud"].(type) {
  14. case string:
  15. aud = append(aud, v)
  16. case []string:
  17. aud = v
  18. case []any:
  19. for _, a := range v {
  20. vs, ok := a.(string)
  21. if !ok {
  22. return false
  23. }
  24. aud = append(aud, vs)
  25. }
  26. }
  27. return verifyAud(aud, cmp, req)
  28. }
  29. // Compares the exp claim against cmp.
  30. // If required is false, this method will return true if the value matches or is unset
  31. func (m MapClaims) VerifyExpiresAt(cmp int64, req bool) bool {
  32. exp, ok := m["exp"]
  33. if !ok {
  34. return !req
  35. }
  36. switch expType := exp.(type) {
  37. case float64:
  38. return verifyExp(int64(expType), cmp, req)
  39. case json.Number:
  40. v, _ := expType.Int64()
  41. return verifyExp(v, cmp, req)
  42. }
  43. return false
  44. }
  45. // Compares the iat claim against cmp.
  46. // If required is false, this method will return true if the value matches or is unset
  47. func (m MapClaims) VerifyIssuedAt(cmp int64, req bool) bool {
  48. iat, ok := m["iat"]
  49. if !ok {
  50. return !req
  51. }
  52. switch iatType := iat.(type) {
  53. case float64:
  54. return verifyIat(int64(iatType), cmp, req)
  55. case json.Number:
  56. v, _ := iatType.Int64()
  57. return verifyIat(v, cmp, req)
  58. }
  59. return false
  60. }
  61. // Compares the iss claim against cmp.
  62. // If required is false, this method will return true if the value matches or is unset
  63. func (m MapClaims) VerifyIssuer(cmp string, req bool) bool {
  64. iss, _ := m["iss"].(string)
  65. return verifyIss(iss, cmp, req)
  66. }
  67. // Compares the nbf claim against cmp.
  68. // If required is false, this method will return true if the value matches or is unset
  69. func (m MapClaims) VerifyNotBefore(cmp int64, req bool) bool {
  70. nbf, ok := m["nbf"]
  71. if !ok {
  72. return !req
  73. }
  74. switch nbfType := nbf.(type) {
  75. case float64:
  76. return verifyNbf(int64(nbfType), cmp, req)
  77. case json.Number:
  78. v, _ := nbfType.Int64()
  79. return verifyNbf(v, cmp, req)
  80. }
  81. return false
  82. }
  83. // Validates time based claims "exp, iat, nbf".
  84. // There is no accounting for clock skew.
  85. // As well, if any of the above claims are not in the token, it will still
  86. // be considered a valid claim.
  87. func (m MapClaims) Valid() error {
  88. vErr := new(ValidationError)
  89. now := TimeFunc().Unix()
  90. if !m.VerifyExpiresAt(now, false) {
  91. vErr.Inner = errors.New("Token is expired")
  92. vErr.Errors |= ValidationErrorExpired
  93. }
  94. if !m.VerifyIssuedAt(now, false) {
  95. vErr.Inner = errors.New("Token used before issued")
  96. vErr.Errors |= ValidationErrorIssuedAt
  97. }
  98. if !m.VerifyNotBefore(now, false) {
  99. vErr.Inner = errors.New("Token is not valid yet")
  100. vErr.Errors |= ValidationErrorNotValidYet
  101. }
  102. if vErr.valid() {
  103. return nil
  104. }
  105. return vErr
  106. }