jwt.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. // provides jwt encode and decode functions
  2. package jwt
  3. import (
  4. "crypto/hmac"
  5. "crypto/sha256"
  6. "errors"
  7. "strings"
  8. "git.clearsky.net.au/cody/gex.git/utils"
  9. "git.clearsky.net.au/cody/gex.git/utils/base64"
  10. )
  11. // encode json bytes to a jwt token string
  12. func Encode(jsonStr []byte, secret string) (string, error) {
  13. header := base64.EncodeURL([]byte("{\"alg\":\"HS256\",\"typ\":\"JWT\"}"))
  14. payload := base64.EncodeURL(jsonStr)
  15. mac := hmac.New(sha256.New, []byte(secret))
  16. mac.Write([]byte(header + "." + payload))
  17. sig := base64.EncodeURL(mac.Sum(nil))
  18. return header + "." + payload + "." + sig, nil
  19. }
  20. // decode a jwt token string to a json string to be processed
  21. func Decode(tokenStr string, secret string) ([]byte, error) {
  22. parts := strings.Split(tokenStr, ".")
  23. if len(parts) < 3 {
  24. err := errors.New("cannot decode JWT")
  25. utils.Err(err)
  26. return []byte(""), err
  27. }
  28. header := parts[0]
  29. payload := parts[1]
  30. sig, err := base64.DecodeURL(parts[2])
  31. if err != nil {
  32. utils.Err(err)
  33. return []byte(""), err
  34. }
  35. mac := hmac.New(sha256.New, []byte(secret))
  36. mac.Write([]byte(header + "." + payload))
  37. expectedSig := mac.Sum(nil)
  38. if !hmac.Equal([]byte(sig), expectedSig) {
  39. return []byte(""), errors.New("signature don't match")
  40. }
  41. jsonStr, err := base64.DecodeURL(payload)
  42. if err != nil {
  43. utils.Err(err)
  44. return []byte(""), err
  45. }
  46. return jsonStr, nil
  47. }