|
|
|
@ -11,15 +11,15 @@ import (
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Token struct {
|
|
|
|
|
Header
|
|
|
|
|
Claims map[string]interface{}
|
|
|
|
|
Signature []byte
|
|
|
|
|
header Header
|
|
|
|
|
claims map[string]interface{}
|
|
|
|
|
signature []byte
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewToken() *Token {
|
|
|
|
|
return &Token{
|
|
|
|
|
Header: DefaultHeader(),
|
|
|
|
|
Claims: map[string]interface{}{},
|
|
|
|
|
header: DefaultHeader(),
|
|
|
|
|
claims: map[string]interface{}{},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -40,34 +40,54 @@ func TokenFromString(token string) *Token {
|
|
|
|
|
signature, _ := base64.RawURLEncoding.DecodeString(parts[2])
|
|
|
|
|
|
|
|
|
|
return &Token{
|
|
|
|
|
Header: header,
|
|
|
|
|
Claims: claims,
|
|
|
|
|
Signature: signature,
|
|
|
|
|
header: header,
|
|
|
|
|
claims: claims,
|
|
|
|
|
signature: signature,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *Token) Sign(secret []byte) {
|
|
|
|
|
t.Signature = t.sign(secret)
|
|
|
|
|
t.signature = t.sign(secret)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *Token) SetExpiry(time time.Time) {
|
|
|
|
|
t.claims[Expiry] = time.Unix()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *Token) SetIssuedAt() {
|
|
|
|
|
t.claims[IssuedAt] = time.Now().Unix()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *Token) SetNotBefore(time time.Time) {
|
|
|
|
|
t.claims[NotBefore] = time.Unix()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *Token) SetClaim(key string, value any) {
|
|
|
|
|
t.claims[key] = value
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t Token) Claim(key string) any {
|
|
|
|
|
return t.claims[key]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t Token) Verify(secret []byte) error {
|
|
|
|
|
if !bytes.Equal(t.sign(secret), t.Signature) {
|
|
|
|
|
if !bytes.Equal(t.sign(secret), t.signature) {
|
|
|
|
|
return ErrSignatureInvalid
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if exp, has := t.Claims[Expiry]; has {
|
|
|
|
|
if exp, has := t.claims[Expiry]; has {
|
|
|
|
|
if int64(exp.(float64)) < time.Now().Unix() {
|
|
|
|
|
return ErrExpired
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if iat, has := t.Claims[IssuedAt]; has {
|
|
|
|
|
if iat, has := t.claims[IssuedAt]; has {
|
|
|
|
|
if int64(iat.(float64)) > time.Now().Unix() {
|
|
|
|
|
return ErrBeforeIssuedAt
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if nbf, has := t.Claims[NotBefore]; has {
|
|
|
|
|
if nbf, has := t.claims[NotBefore]; has {
|
|
|
|
|
if int64(nbf.(float64)) > time.Now().Unix() {
|
|
|
|
|
return ErrBeforeNotBefore
|
|
|
|
|
}
|
|
|
|
@ -82,7 +102,7 @@ func (t Token) String() string {
|
|
|
|
|
|
|
|
|
|
buf.Write(t.encodeHeaderAndClaims())
|
|
|
|
|
buf.WriteByte('.')
|
|
|
|
|
be.Write(t.Signature)
|
|
|
|
|
be.Write(t.signature)
|
|
|
|
|
be.Close()
|
|
|
|
|
return buf.String()
|
|
|
|
|
}
|
|
|
|
@ -97,11 +117,11 @@ func (t Token) encodeHeaderAndClaims() []byte {
|
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
|
be := base64.NewEncoder(base64.RawURLEncoding, buf)
|
|
|
|
|
|
|
|
|
|
headerData, _ := json.Marshal(t.Header)
|
|
|
|
|
headerData, _ := json.Marshal(t.header)
|
|
|
|
|
be.Write(headerData)
|
|
|
|
|
buf.WriteByte('.')
|
|
|
|
|
|
|
|
|
|
claimsData, _ := json.Marshal(t.Claims)
|
|
|
|
|
claimsData, _ := json.Marshal(t.claims)
|
|
|
|
|
be.Write(claimsData)
|
|
|
|
|
be.Close()
|
|
|
|
|
return buf.Bytes()
|
|
|
|
|