jwt/token.go
2018-09-13 11:39:49 +02:00

104 lines
2 KiB
Go

// Copyright (C) 2018 Marius Schellenberger
package jwt
import (
"encoding/base64"
"encoding/json"
"strings"
)
// Token is the JWT token representation
type Token struct {
raw string
data string
signature string
rawSignature []byte
header Claims
Claims Claims
}
// String returns the tokens encoded string
func (t *Token) String() string {
return t.raw
}
// Sig returns the Tokens URLEncoded signature
func (t *Token) Sig() string {
return t.signature
}
// RawSig returns the Tokens raw signature
func (t *Token) RawSig() []byte {
return t.rawSignature
}
// Header returns the Tokens header
func (t *Token) Header() Claims {
return t.header
}
// Data returns the first two token fields
func (t *Token) Data() string {
return t.data
}
// NewToken returns a new *Token using the provided hash algorithm and claims
// If claims is nil, an empty map is used
// If hash is nil, HS256 is used
func NewToken(claims Claims, hash Hash) *Token {
if claims == nil {
claims = make(Claims)
}
if hash == nil {
hash = NewHS256()
}
return &Token{
header: Claims{
"alg": hash.Alg(),
"typ": typ,
},
Claims: claims,
}
}
// DecodeToken decodes a raw string token into a *Token object
func DecodeToken(token string) (t *Token, err error) {
if token == "" {
return nil, ErrEmptyToken
}
parts := strings.Split(token, ".")
if len(parts) < 3 {
return nil, ErrMissingTokenParts
}
if len(parts) > 3 {
return nil, ErrNoJWT
}
for _, v := range parts {
if v == "" {
return nil, ErrNoJWT
}
}
t = new(Token)
header, err := base64.URLEncoding.DecodeString(parts[0])
if err != nil {
return
}
err = json.Unmarshal(header, &t.header)
if err != nil {
return
}
claims, err := base64.URLEncoding.DecodeString(parts[1])
if err != nil {
return
}
err = json.Unmarshal(claims, &t.Claims)
if err != nil {
return
}
t.rawSignature, err = base64.URLEncoding.DecodeString(parts[2])
t.signature = parts[2]
t.data = strings.Join(parts[:2], ".")
t.raw = token
return
}