First commit

master
Niels Westland 2 years ago
commit 71652a3d3a

2
.gitignore vendored

@ -0,0 +1,2 @@
go.mod
*.txt

@ -0,0 +1,13 @@
package nwjwt
type Header struct {
Algorithm string `json:"alg"`
Type string `json:"typ"`
}
func DefaultHeader() Header {
return Header{
Algorithm: "HS256",
Type: "JWT",
}
}

@ -0,0 +1,26 @@
package nwjwt
import "crypto/rand"
const (
Issuer = "iss"
Subject = "sub"
Audience = "aud"
Expiry = "exp"
NotBefore = "nbf"
IssuedAt = "iat"
ID = "jti"
)
//https://auth0.com/docs/security/tokens/json-web-tokens/json-web-token-claims
//https://en.wikipedia.org/wiki/JSON_Web_Token
//https://connect2id.com/products/nimbus-jose-jwt/examples/jwk-generation
func GenerateSecret() []byte {
key := make([]byte, 256)
_, err := rand.Read(key)
if err != nil {
return nil
}
return key
}

@ -0,0 +1,23 @@
package nwjwt
import (
// "encoding/base64"
"os"
"testing"
)
func Test(t *testing.T) {
o, _ := os.Create("test.txt")
// secret := GenerateSecret()
// o.WriteString(base64.RawURLEncoding.EncodeToString(secret))
// o.WriteString("\n")
token := NewToken()
token.Claims[Expiry] = 1640212096
token.Sign([]byte("test"))
o.WriteString(token.String())
o.Close()
}

@ -0,0 +1,108 @@
package nwjwt
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"strings"
"time"
)
type Token struct {
Header
Claims map[string]interface{}
Signature []byte
}
func NewToken() *Token {
return &Token{
Header: DefaultHeader(),
Claims: map[string]interface{}{},
}
}
func TokenFromString(token string) *Token {
parts := strings.SplitN(token, ".", 2)
if len(parts) != 3 {
return nil
}
var header Header
headerData, _ := base64.RawURLEncoding.DecodeString(parts[0])
json.Unmarshal(headerData, &header)
var claims map[string]interface{}
claimsData, _ := base64.RawURLEncoding.DecodeString(parts[1])
json.Unmarshal(claimsData, &claims)
signature, _ := base64.RawURLEncoding.DecodeString(parts[2])
return &Token{
Header: header,
Claims: claims,
Signature: signature,
}
}
func (t *Token) Sign(secret []byte) {
t.Signature = t.sign(secret)
}
func (t *Token) Verify(secret []byte) bool {
if exp, has := t.Claims[Expiry]; has {
if int64(exp.(float64)) < time.Now().Unix() {
return false
}
}
if iat, has := t.Claims[IssuedAt]; has {
if int64(iat.(float64)) > time.Now().Unix() {
return false
}
}
if nbf, has := t.Claims[NotBefore]; has {
if int64(nbf.(float64)) > time.Now().Unix() {
return false
}
}
newSignature := t.sign(secret)
return bytes.Equal(newSignature, t.Signature)
}
func (t Token) String() string {
buf := new(bytes.Buffer)
be := base64.NewEncoder(base64.RawURLEncoding, buf)
headerData, _ := json.Marshal(t.Header)
be.Write(headerData)
buf.WriteByte('.')
claimsData, _ := json.Marshal(t.Claims)
be.Write(claimsData)
buf.WriteByte('.')
be.Write(t.Signature)
be.Close()
return buf.String()
}
func (t Token) sign(secret []byte) []byte {
buf := new(bytes.Buffer)
be := base64.NewEncoder(base64.RawURLEncoding, buf)
headerData, _ := json.Marshal(t.Header)
be.Write(headerData)
buf.WriteByte('.')
claimsData, _ := json.Marshal(t.Claims)
be.Write(claimsData)
be.Close()
mac := hmac.New(sha256.New, secret)
mac.Write(buf.Bytes())
return mac.Sum(nil)
}
Loading…
Cancel
Save