token.go (3319B)
1 package jwt 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "strings" 7 "time" 8 ) 9 10 // TimeFunc provides the current time when parsing token to validate "exp" claim (expiration time). 11 // You can override it to use another time value. This is useful for testing or if your 12 // server uses a different time zone than your tokens. 13 var TimeFunc = time.Now 14 15 // Parse methods use this callback function to supply 16 // the key for verification. The function receives the parsed, 17 // but unverified Token. This allows you to use properties in the 18 // Header of the token (such as `kid`) to identify which key to use. 19 type Keyfunc func(*Token) (interface{}, error) 20 21 // A JWT Token. Different fields will be used depending on whether you're 22 // creating or parsing/verifying a token. 23 type Token struct { 24 Raw string // The raw token. Populated when you Parse a token 25 Method SigningMethod // The signing method used or to be used 26 Header map[string]interface{} // The first segment of the token 27 Claims Claims // The second segment of the token 28 Signature string // The third segment of the token. Populated when you Parse a token 29 Valid bool // Is the token valid? Populated when you Parse/Verify a token 30 } 31 32 // Create a new Token. Takes a signing method 33 func New(method SigningMethod) *Token { 34 return NewWithClaims(method, MapClaims{}) 35 } 36 37 func NewWithClaims(method SigningMethod, claims Claims) *Token { 38 return &Token{ 39 Header: map[string]interface{}{ 40 "typ": "JWT", 41 "alg": method.Alg(), 42 }, 43 Claims: claims, 44 Method: method, 45 } 46 } 47 48 // Get the complete, signed token 49 func (t *Token) SignedString(key interface{}) (string, error) { 50 var sig, sstr string 51 var err error 52 if sstr, err = t.SigningString(); err != nil { 53 return "", err 54 } 55 if sig, err = t.Method.Sign(sstr, key); err != nil { 56 return "", err 57 } 58 return strings.Join([]string{sstr, sig}, "."), nil 59 } 60 61 // Generate the signing string. This is the 62 // most expensive part of the whole deal. Unless you 63 // need this for something special, just go straight for 64 // the SignedString. 65 func (t *Token) SigningString() (string, error) { 66 var err error 67 parts := make([]string, 2) 68 for i := range parts { 69 var jsonValue []byte 70 if i == 0 { 71 if jsonValue, err = json.Marshal(t.Header); err != nil { 72 return "", err 73 } 74 } else { 75 if jsonValue, err = json.Marshal(t.Claims); err != nil { 76 return "", err 77 } 78 } 79 80 parts[i] = EncodeSegment(jsonValue) 81 } 82 return strings.Join(parts, "."), nil 83 } 84 85 // Parse, validate, and return a token. 86 // keyFunc will receive the parsed token and should return the key for validating. 87 // If everything is kosher, err will be nil 88 func Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { 89 return new(Parser).Parse(tokenString, keyFunc) 90 } 91 92 func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) { 93 return new(Parser).ParseWithClaims(tokenString, claims, keyFunc) 94 } 95 96 // Encode JWT specific base64url encoding with padding stripped 97 func EncodeSegment(seg []byte) string { 98 return base64.RawURLEncoding.EncodeToString(seg) 99 } 100 101 // Decode JWT specific base64url encoding with padding stripped 102 func DecodeSegment(seg string) ([]byte, error) { 103 return base64.RawURLEncoding.DecodeString(seg) 104 }