Skip to content

Instantly share code, notes, and snippets.

@yusuke024
Last active July 13, 2016 12:52
Show Gist options
  • Save yusuke024/1a0f9fd829294c0bab48783a5c944a5f to your computer and use it in GitHub Desktop.
Save yusuke024/1a0f9fd829294c0bab48783a5c944a5f to your computer and use it in GitHub Desktop.
package main
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
)
// JWTHeader ...
type JWTHeader struct {
Algorithm string `json:"alg"`
Type string `json:"typ"`
}
// JWTPayload ...
type JWTPayload struct {
Subject string `json:"sub"`
Email string `json:"email"`
}
func main() {
key := []byte("123456789")
jwt := JWTEncode(&JWTPayload{"ABCDEFGHIJKLMOPQRSTUVWXYZ", "[email protected]"}, key)
fmt.Println(jwt)
payload := JWTPayload{}
JWTDecode(jwt, key, &payload)
}
var header, _ = json.Marshal(JWTHeader{"HS256", "JWT"})
// JWTEncode ...
func JWTEncode(payload interface{}, key []byte) []byte {
marshalledPayload, _ := json.Marshal(payload)
headerSize := base64.RawURLEncoding.EncodedLen(len(header))
payloadSize := base64.RawURLEncoding.EncodedLen(len(marshalledPayload))
signatureSize := base64.RawURLEncoding.EncodedLen(sha256.Size)
jwt := make([]byte, headerSize+1+payloadSize+1+signatureSize)
base64.RawURLEncoding.Encode(jwt, header)
jwt[headerSize] = byte('.')
base64.RawURLEncoding.Encode(jwt[headerSize+1:], marshalledPayload)
jwt[headerSize+1+payloadSize] = byte('.')
mac := hmac.New(sha256.New, key)
mac.Write(jwt[:headerSize+1+payloadSize])
base64.RawURLEncoding.Encode(jwt[headerSize+1+payloadSize+1:], mac.Sum(nil))
return jwt
}
// JWTDecode ...
func JWTDecode(token, key []byte, object interface{}) error {
headerSize := bytes.IndexRune(token, '.')
payloadSize := bytes.IndexRune(token[headerSize+1:], '.')
signature := make([]byte, sha256.Size)
base64.RawURLEncoding.Decode(signature, token[headerSize+1+payloadSize+1:])
mac := hmac.New(sha256.New, key)
mac.Write(token[:headerSize+1+payloadSize])
if !hmac.Equal(signature, mac.Sum(nil)) {
return errors.New("invalid signature")
}
header := make([]byte, base64.RawURLEncoding.DecodedLen(headerSize))
base64.RawURLEncoding.Decode(header, token[:headerSize])
headerStruct := JWTHeader{}
if err := json.Unmarshal(header, &headerStruct); err != nil {
return err
}
payload := make([]byte, base64.RawURLEncoding.DecodedLen(payloadSize))
base64.RawURLEncoding.Decode(payload, token[headerSize+1:headerSize+1+payloadSize])
if err := json.Unmarshal(payload, object); err != nil {
return err
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment