Skip to content

Instantly share code, notes, and snippets.

@prongbang
Last active March 9, 2024 15:57
Show Gist options
  • Save prongbang/1efb2538fda731e0b78db55151387d9a to your computer and use it in GitHub Desktop.
Save prongbang/1efb2538fda731e0b78db55151387d9a to your computer and use it in GitHub Desktop.
package tokenx
import (
"encoding/hex"
"github.com/go-jose/go-jose/v4"
"github.com/goccy/go-json"
)
type JWXToken Token
type jwxToken struct {
}
func (j *jwxToken) Generate(payload map[string]any, key string) (string, error) {
secretKey, err := hex.DecodeString(key)
if err != nil {
return "", err
}
jwk := &jose.JSONWebKey{Key: secretKey}
// Create a new JSON Web Encryption object with claims
encrypter, err := jose.NewEncrypter(
jose.A256GCM,
jose.Recipient{
Algorithm: jose.A256GCMKW,
Key: jwk,
},
&jose.EncrypterOptions{
Compression: jose.NONE,
},
)
if err != nil {
return "", err
}
// Convert payload to string
payloadByte, err := json.Marshal(payload)
if err != nil {
return "", err
}
// Set additional claims in the JWE
tkn, err := encrypter.Encrypt(payloadByte)
if err != nil {
return "", err
}
return tkn.CompactSerialize()
}
func (j *jwxToken) Verify(token, key string) bool {
payload, err := j.decrypt(token, key)
return payload != nil && err == nil
}
func (j *jwxToken) Parse(token, key string) (map[string]any, error) {
decrypted, err := j.decrypt(token, key)
if err != nil {
return nil, err
}
// Parse the decrypted payload to check expiration time
claims := map[string]any{}
if err = json.Unmarshal(decrypted, &claims); err != nil {
return nil, err
}
return claims, nil
}
func (j *jwxToken) decrypt(token string, key string) ([]byte, error) {
secretKey, err := hex.DecodeString(key)
if err != nil {
return nil, err
}
jwk := jose.JSONWebKey{Key: secretKey}
// Parse the JWE
parsed, err := jose.ParseEncrypted(
token,
[]jose.KeyAlgorithm{jose.A256GCMKW},
[]jose.ContentEncryption{jose.A256GCM},
)
if err != nil {
return nil, err
}
// Decrypt the JWE
decrypted, err := parsed.Decrypt(&jwk)
if err != nil {
return nil, err
}
return decrypted, nil
}
func NewJWX() JWXToken {
return &jwxToken{}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment