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.

map_claims.go 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package jwt
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. )
  6. // MapClaims is a claims type that uses the map[string]interface{} for JSON
  7. // decoding. This is the default claims type if you don't supply one
  8. type MapClaims map[string]interface{}
  9. // GetExpirationTime implements the Claims interface.
  10. func (m MapClaims) GetExpirationTime() (*NumericDate, error) {
  11. return m.parseNumericDate("exp")
  12. }
  13. // GetNotBefore implements the Claims interface.
  14. func (m MapClaims) GetNotBefore() (*NumericDate, error) {
  15. return m.parseNumericDate("nbf")
  16. }
  17. // GetIssuedAt implements the Claims interface.
  18. func (m MapClaims) GetIssuedAt() (*NumericDate, error) {
  19. return m.parseNumericDate("iat")
  20. }
  21. // GetAudience implements the Claims interface.
  22. func (m MapClaims) GetAudience() (ClaimStrings, error) {
  23. return m.parseClaimsString("aud")
  24. }
  25. // GetIssuer implements the Claims interface.
  26. func (m MapClaims) GetIssuer() (string, error) {
  27. return m.parseString("iss")
  28. }
  29. // GetSubject implements the Claims interface.
  30. func (m MapClaims) GetSubject() (string, error) {
  31. return m.parseString("sub")
  32. }
  33. // parseNumericDate tries to parse a key in the map claims type as a number
  34. // date. This will succeed, if the underlying type is either a [float64] or a
  35. // [json.Number]. Otherwise, nil will be returned.
  36. func (m MapClaims) parseNumericDate(key string) (*NumericDate, error) {
  37. v, ok := m[key]
  38. if !ok {
  39. return nil, nil
  40. }
  41. switch exp := v.(type) {
  42. case float64:
  43. if exp == 0 {
  44. return nil, nil
  45. }
  46. return newNumericDateFromSeconds(exp), nil
  47. case json.Number:
  48. v, _ := exp.Float64()
  49. return newNumericDateFromSeconds(v), nil
  50. }
  51. return nil, newError(fmt.Sprintf("%s is invalid", key), ErrInvalidType)
  52. }
  53. // parseClaimsString tries to parse a key in the map claims type as a
  54. // [ClaimsStrings] type, which can either be a string or an array of string.
  55. func (m MapClaims) parseClaimsString(key string) (ClaimStrings, error) {
  56. var cs []string
  57. switch v := m[key].(type) {
  58. case string:
  59. cs = append(cs, v)
  60. case []string:
  61. cs = v
  62. case []interface{}:
  63. for _, a := range v {
  64. vs, ok := a.(string)
  65. if !ok {
  66. return nil, newError(fmt.Sprintf("%s is invalid", key), ErrInvalidType)
  67. }
  68. cs = append(cs, vs)
  69. }
  70. }
  71. return cs, nil
  72. }
  73. // parseString tries to parse a key in the map claims type as a [string] type.
  74. // If the key does not exist, an empty string is returned. If the key has the
  75. // wrong type, an error is returned.
  76. func (m MapClaims) parseString(key string) (string, error) {
  77. var (
  78. ok bool
  79. raw interface{}
  80. iss string
  81. )
  82. raw, ok = m[key]
  83. if !ok {
  84. return "", nil
  85. }
  86. iss, ok = raw.(string)
  87. if !ok {
  88. return "", newError(fmt.Sprintf("%s is invalid", key), ErrInvalidType)
  89. }
  90. return iss, nil
  91. }