Added a few new methods to use custom Claims structs.

Must implement interface Claims, which means there is a Valid method.
This commit is contained in:
Jamie Stackhouse 2015-07-14 14:34:09 -03:00
parent fa9a0b8c45
commit febded4195
1 changed files with 35 additions and 4 deletions

39
jwt.go
View File

@ -75,6 +75,17 @@ func New(method SigningMethod) *Token {
} }
} }
func NewWithClaims(method SigningMethod, claims Claims) *Token {
return &Token{
Header: map[string]interface{}{
"typ": "JWT",
"alg": method.Alg(),
},
Claims: claims,
Method: method,
}
}
// Get the complete, signed token // Get the complete, signed token
func (t *Token) SignedString(key interface{}) (string, error) { func (t *Token) SignedString(key interface{}) (string, error) {
var sig, sstr string var sig, sstr string
@ -116,13 +127,20 @@ func (t *Token) SigningString() (string, error) {
// keyFunc will receive the parsed token and should return the key for validating. // keyFunc will receive the parsed token and should return the key for validating.
// If everything is kosher, err will be nil // If everything is kosher, err will be nil
func Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { func Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
return ParseWithClaims(tokenString, keyFunc, make(MapClaim))
}
func ParseWithClaims(tokenString string, keyFunc Keyfunc, claims Claims) (*Token, error) {
parts := strings.Split(tokenString, ".") parts := strings.Split(tokenString, ".")
if len(parts) != 3 { if len(parts) != 3 {
return nil, &ValidationError{err: "token contains an invalid number of segments", Errors: ValidationErrorMalformed} return nil, &ValidationError{err: "token contains an invalid number of segments", Errors: ValidationErrorMalformed}
} }
var err error var err error
token := &Token{Raw: tokenString} token := &Token{
Raw: tokenString,
}
// parse Header // parse Header
var headerBytes []byte var headerBytes []byte
if headerBytes, err = DecodeSegment(parts[0]); err != nil { if headerBytes, err = DecodeSegment(parts[0]); err != nil {
@ -134,12 +152,15 @@ func Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
// parse Claims // parse Claims
var claimBytes []byte var claimBytes []byte
if claimBytes, err = DecodeSegment(parts[1]); err != nil { if claimBytes, err = DecodeSegment(parts[1]); err != nil {
return token, &ValidationError{err: err.Error(), Errors: ValidationErrorMalformed} return token, &ValidationError{err: err.Error(), Errors: ValidationErrorMalformed}
} }
if err = json.Unmarshal(claimBytes, &token.Claims); err != nil {
if err = json.Unmarshal(claimBytes, &claims); err != nil {
return token, &ValidationError{err: err.Error(), Errors: ValidationErrorMalformed} return token, &ValidationError{err: err.Error(), Errors: ValidationErrorMalformed}
} }
token.Claims = claims
// Lookup signature method // Lookup signature method
if method, ok := token.Header["alg"].(string); ok { if method, ok := token.Header["alg"].(string); ok {
@ -163,7 +184,17 @@ func Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
// Check expiration times // Check expiration times
err = token.Claims.Valid() err = token.Claims.Valid()
vErr := err.(ValidationError) var vErr *ValidationError
// If the Claims Valid returned an error, check if it is a validation error,
// if not, convert it into one with a generic ClaimsInvalid flag set
if err != nil {
if e, ok := err.(*ValidationError); !ok {
vErr = &ValidationError{err: err.Error(), Errors: ValidationErrorClaimsInvalid}
} else {
vErr = e
}
}
// Perform validation // Perform validation
if err = token.Method.Verify(strings.Join(parts[0:2], "."), parts[2], key); err != nil { if err = token.Method.Verify(strings.Join(parts[0:2], "."), parts[2], key); err != nil {
@ -171,7 +202,7 @@ func Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
vErr.Errors |= ValidationErrorSignatureInvalid vErr.Errors |= ValidationErrorSignatureInvalid
} }
if vErr.valid() { if vErr == nil || vErr.valid() {
token.Valid = true token.Valid = true
return token, nil return token, nil
} }