From c97496f7ab6574b6cbcc535385f8d04d30e93d20 Mon Sep 17 00:00:00 2001 From: "Vojtech Vitek (V-Teq)" Date: Mon, 11 Jul 2016 17:51:29 -0400 Subject: [PATCH] JWT Auth for go1.7 --- jwtauth.go | 33 +++++++++++++++++---------------- jwtauth_test.go | 15 ++++++++------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/jwtauth.go b/jwtauth.go index 06c440b..c0bdaab 100644 --- a/jwtauth.go +++ b/jwtauth.go @@ -1,15 +1,14 @@ package jwtauth import ( + "context" "encoding/json" "errors" "net/http" "strings" "time" - "github.com/dgrijalva/jwt-go" - "github.com/pressly/chi" - "golang.org/x/net/context" + jwt "github.com/dgrijalva/jwt-go" ) var ( @@ -59,14 +58,14 @@ func NewWithParser(alg string, parser *jwt.Parser, signKey []byte, verifyKey []b // and respond to the client accordingly. A generic Authenticator // middleware is provided by this package, that will return a 401 // message for all unverified tokens, see jwtauth.Authenticator. -func (ja *JwtAuth) Verifier(next chi.Handler) chi.Handler { +func (ja *JwtAuth) Verifier(next http.Handler) http.Handler { return ja.Verify("")(next) } -func (ja *JwtAuth) Verify(paramAliases ...string) func(chi.Handler) chi.Handler { - return func(next chi.Handler) chi.Handler { - hfn := func(ctx context.Context, w http.ResponseWriter, r *http.Request) { - +func (ja *JwtAuth) Verify(paramAliases ...string) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + hfn := func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() var tokenStr string var err error @@ -113,14 +112,14 @@ func (ja *JwtAuth) Verify(paramAliases ...string) func(chi.Handler) chi.Handler } ctx = ja.SetContext(ctx, token, err) - next.ServeHTTPC(ctx, w, r) + next.ServeHTTP(w, r.WithContext(ctx)) return } if token == nil || !token.Valid || token.Method != ja.signer { err = ErrUnauthorized ctx = ja.SetContext(ctx, token, err) - next.ServeHTTPC(ctx, w, r) + next.ServeHTTP(w, r.WithContext(ctx)) return } @@ -128,15 +127,15 @@ func (ja *JwtAuth) Verify(paramAliases ...string) func(chi.Handler) chi.Handler if ja.IsExpired(token) { err = ErrExpired ctx = ja.SetContext(ctx, token, err) - next.ServeHTTPC(ctx, w, r) + next.ServeHTTP(w, r.WithContext(ctx)) return } // Valid! pass it down the context to an authenticator middleware ctx = ja.SetContext(ctx, token, err) - next.ServeHTTPC(ctx, w, r) + next.ServeHTTP(w, r.WithContext(ctx)) } - return chi.HandlerFunc(hfn) + return http.HandlerFunc(hfn) } } @@ -194,8 +193,10 @@ func (ja *JwtAuth) IsExpired(t *jwt.Token) bool { // the Verifier middleware. The Authenticator sends a 401 Unauthorized response for // all unverified tokens and passes the good ones through. It's just fine until you // decide to write something similar and customize your client response. -func Authenticator(next chi.Handler) chi.Handler { - return chi.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { +func Authenticator(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + if jwtErr, ok := ctx.Value("jwt.err").(error); ok { if jwtErr != nil { http.Error(w, http.StatusText(401), 401) @@ -210,7 +211,7 @@ func Authenticator(next chi.Handler) chi.Handler { } // Token is authenticated, pass it through - next.ServeHTTPC(ctx, w, r) + next.ServeHTTP(w, r) }) } diff --git a/jwtauth_test.go b/jwtauth_test.go index 3c04e49..937483b 100644 --- a/jwtauth_test.go +++ b/jwtauth_test.go @@ -12,7 +12,6 @@ import ( "github.com/dgrijalva/jwt-go" "github.com/goware/jwtauth" "github.com/pressly/chi" - "golang.org/x/net/context" ) var ( @@ -33,7 +32,7 @@ func TestSimple(t *testing.T) { r.Use(TokenAuth.Verifier, jwtauth.Authenticator) - r.Get("/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { + r.Get("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("welcome")) }) @@ -78,8 +77,10 @@ func TestMore(t *testing.T) { r.Group(func(r chi.Router) { r.Use(TokenAuth.Verifier) - authenticator := func(next chi.Handler) chi.Handler { - return chi.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { + authenticator := func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + if jwtErr, ok := ctx.Value("jwt.err").(error); ok { switch jwtErr { default: @@ -103,19 +104,19 @@ func TestMore(t *testing.T) { } // Token is authenticated, pass it through - next.ServeHTTPC(ctx, w, r) + next.ServeHTTP(w, r) }) } r.Use(authenticator) - r.Get("/admin", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { + r.Get("/admin", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("protected")) }) }) // Public routes r.Group(func(r chi.Router) { - r.Get("/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { + r.Get("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("welcome")) }) })