claims.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*-
  2. * Copyright 2016 Zbigniew Mandziejewicz
  3. * Copyright 2016 Square, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package jwt
  18. import (
  19. "encoding/json"
  20. "strconv"
  21. "time"
  22. )
  23. // Claims represents public claim values (as specified in RFC 7519).
  24. type Claims struct {
  25. Issuer string `json:"iss,omitempty"`
  26. Subject string `json:"sub,omitempty"`
  27. Audience Audience `json:"aud,omitempty"`
  28. Expiry NumericDate `json:"exp,omitempty"`
  29. NotBefore NumericDate `json:"nbf,omitempty"`
  30. IssuedAt NumericDate `json:"iat,omitempty"`
  31. ID string `json:"jti,omitempty"`
  32. }
  33. // NumericDate represents date and time as the number of seconds since the
  34. // epoch, including leap seconds. Non-integer values can be represented
  35. // in the serialized format, but we round to the nearest second.
  36. type NumericDate int64
  37. // NewNumericDate constructs NumericDate from time.Time value.
  38. func NewNumericDate(t time.Time) NumericDate {
  39. if t.IsZero() {
  40. return NumericDate(0)
  41. }
  42. // While RFC 7519 technically states that NumericDate values may be
  43. // non-integer values, we don't bother serializing timestamps in
  44. // claims with sub-second accurancy and just round to the nearest
  45. // second instead. Not convined sub-second accuracy is useful here.
  46. return NumericDate(t.Unix())
  47. }
  48. // MarshalJSON serializes the given NumericDate into its JSON representation.
  49. func (n NumericDate) MarshalJSON() ([]byte, error) {
  50. return []byte(strconv.FormatInt(int64(n), 10)), nil
  51. }
  52. // UnmarshalJSON reads a date from its JSON representation.
  53. func (n *NumericDate) UnmarshalJSON(b []byte) error {
  54. s := string(b)
  55. f, err := strconv.ParseFloat(s, 64)
  56. if err != nil {
  57. return ErrUnmarshalNumericDate
  58. }
  59. *n = NumericDate(f)
  60. return nil
  61. }
  62. // Time returns time.Time representation of NumericDate.
  63. func (n NumericDate) Time() time.Time {
  64. return time.Unix(int64(n), 0)
  65. }
  66. // Audience represents the recipents that the token is intended for.
  67. type Audience []string
  68. // UnmarshalJSON reads an audience from its JSON representation.
  69. func (s *Audience) UnmarshalJSON(b []byte) error {
  70. var v interface{}
  71. if err := json.Unmarshal(b, &v); err != nil {
  72. return err
  73. }
  74. switch v := v.(type) {
  75. case string:
  76. *s = []string{v}
  77. case []interface{}:
  78. a := make([]string, len(v))
  79. for i, e := range v {
  80. s, ok := e.(string)
  81. if !ok {
  82. return ErrUnmarshalAudience
  83. }
  84. a[i] = s
  85. }
  86. *s = a
  87. default:
  88. return ErrUnmarshalAudience
  89. }
  90. return nil
  91. }
  92. func (s Audience) Contains(v string) bool {
  93. for _, a := range s {
  94. if a == v {
  95. return true
  96. }
  97. }
  98. return false
  99. }