diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..247177e --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +# ---> Go +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +*.log +tmp \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..3722599 --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module jwt + +go 1.17 + +require ( + github.com/golang-jwt/jwt v3.2.2+incompatible + github.com/husobee/vestigo v1.1.1 +) + +require github.com/stretchr/testify v1.7.1 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..9cbfc1a --- /dev/null +++ b/go.sum @@ -0,0 +1,14 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/husobee/vestigo v1.1.1 h1:bsReVP78YhmHUn/nQ4AxIEfObmWMSLGLGXP1OwgFa9s= +github.com/husobee/vestigo v1.1.1/go.mod h1:JigD7C8lzUfpo1uzqYgefpyZLswrtJbAQxMw7ds7YCE= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go new file mode 100644 index 0000000..4ae9ccb --- /dev/null +++ b/main.go @@ -0,0 +1,74 @@ +package main + +import ( + "fmt" + "net/http" + "os" + "strings" + "time" + + "github.com/golang-jwt/jwt" + "github.com/husobee/vestigo" +) + +// For HMAC signing method, the key can be any []byte. It is recommended to generate +// a key using crypto/rand or something equivalent. You need the same key for signing +// and validating. +var hmacSampleSecret = []byte("a") + +func main() { + if len(os.Args) == 2 && os.Args[1] == "token" { + generateToken() + os.Exit(0) + } + + router := vestigo.NewRouter() + router.Get("/", Auth(func(w http.ResponseWriter, r *http.Request) { + + })) + http.ListenAndServe(":8080", router) +} + +func Auth(f http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + authheader, ok := r.Header["Authorization"] + if !ok { + http.Error(w, "Missing token", http.StatusBadRequest) + return + } + tokenString := strings.Split(authheader[0], " ")[1] + + token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { + if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { + return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) + } + + return hmacSampleSecret, nil + }) + if err != nil { + http.Error(w, "Bad token", http.StatusBadRequest) + return + } + + if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { + fmt.Println(claims["foo"], claims["nbf"]) + f(w, r) + } else { + fmt.Println(err) + http.Error(w, "Forbidden", http.StatusUnauthorized) + } + + } +} + +func generateToken() { + token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ + "foo": "bar", + "nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(), + }) + tokenString, err := token.SignedString(hmacSampleSecret) + if err != nil { + panic(err) + } + fmt.Println(tokenString) +}