JWT Auth for go1.7

This commit is contained in:
Vojtech Vitek (V-Teq) 2016-07-11 17:51:29 -04:00
parent cf1ac5a102
commit c97496f7ab
2 changed files with 25 additions and 23 deletions

View file

@ -1,15 +1,14 @@
package jwtauth package jwtauth
import ( import (
"context"
"encoding/json" "encoding/json"
"errors" "errors"
"net/http" "net/http"
"strings" "strings"
"time" "time"
"github.com/dgrijalva/jwt-go" jwt "github.com/dgrijalva/jwt-go"
"github.com/pressly/chi"
"golang.org/x/net/context"
) )
var ( 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 // and respond to the client accordingly. A generic Authenticator
// middleware is provided by this package, that will return a 401 // middleware is provided by this package, that will return a 401
// message for all unverified tokens, see jwtauth.Authenticator. // 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) return ja.Verify("")(next)
} }
func (ja *JwtAuth) Verify(paramAliases ...string) func(chi.Handler) chi.Handler { func (ja *JwtAuth) Verify(paramAliases ...string) func(http.Handler) http.Handler {
return func(next chi.Handler) chi.Handler { return func(next http.Handler) http.Handler {
hfn := func(ctx context.Context, w http.ResponseWriter, r *http.Request) { hfn := func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var tokenStr string var tokenStr string
var err error var err error
@ -113,14 +112,14 @@ func (ja *JwtAuth) Verify(paramAliases ...string) func(chi.Handler) chi.Handler
} }
ctx = ja.SetContext(ctx, token, err) ctx = ja.SetContext(ctx, token, err)
next.ServeHTTPC(ctx, w, r) next.ServeHTTP(w, r.WithContext(ctx))
return return
} }
if token == nil || !token.Valid || token.Method != ja.signer { if token == nil || !token.Valid || token.Method != ja.signer {
err = ErrUnauthorized err = ErrUnauthorized
ctx = ja.SetContext(ctx, token, err) ctx = ja.SetContext(ctx, token, err)
next.ServeHTTPC(ctx, w, r) next.ServeHTTP(w, r.WithContext(ctx))
return return
} }
@ -128,15 +127,15 @@ func (ja *JwtAuth) Verify(paramAliases ...string) func(chi.Handler) chi.Handler
if ja.IsExpired(token) { if ja.IsExpired(token) {
err = ErrExpired err = ErrExpired
ctx = ja.SetContext(ctx, token, err) ctx = ja.SetContext(ctx, token, err)
next.ServeHTTPC(ctx, w, r) next.ServeHTTP(w, r.WithContext(ctx))
return return
} }
// Valid! pass it down the context to an authenticator middleware // Valid! pass it down the context to an authenticator middleware
ctx = ja.SetContext(ctx, token, err) 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 // 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 // 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. // decide to write something similar and customize your client response.
func Authenticator(next chi.Handler) chi.Handler { func Authenticator(next http.Handler) http.Handler {
return chi.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if jwtErr, ok := ctx.Value("jwt.err").(error); ok { if jwtErr, ok := ctx.Value("jwt.err").(error); ok {
if jwtErr != nil { if jwtErr != nil {
http.Error(w, http.StatusText(401), 401) http.Error(w, http.StatusText(401), 401)
@ -210,7 +211,7 @@ func Authenticator(next chi.Handler) chi.Handler {
} }
// Token is authenticated, pass it through // Token is authenticated, pass it through
next.ServeHTTPC(ctx, w, r) next.ServeHTTP(w, r)
}) })
} }

View file

@ -12,7 +12,6 @@ import (
"github.com/dgrijalva/jwt-go" "github.com/dgrijalva/jwt-go"
"github.com/goware/jwtauth" "github.com/goware/jwtauth"
"github.com/pressly/chi" "github.com/pressly/chi"
"golang.org/x/net/context"
) )
var ( var (
@ -33,7 +32,7 @@ func TestSimple(t *testing.T) {
r.Use(TokenAuth.Verifier, jwtauth.Authenticator) 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")) w.Write([]byte("welcome"))
}) })
@ -78,8 +77,10 @@ func TestMore(t *testing.T) {
r.Group(func(r chi.Router) { r.Group(func(r chi.Router) {
r.Use(TokenAuth.Verifier) r.Use(TokenAuth.Verifier)
authenticator := func(next chi.Handler) chi.Handler { authenticator := func(next http.Handler) http.Handler {
return chi.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if jwtErr, ok := ctx.Value("jwt.err").(error); ok { if jwtErr, ok := ctx.Value("jwt.err").(error); ok {
switch jwtErr { switch jwtErr {
default: default:
@ -103,19 +104,19 @@ func TestMore(t *testing.T) {
} }
// Token is authenticated, pass it through // Token is authenticated, pass it through
next.ServeHTTPC(ctx, w, r) next.ServeHTTP(w, r)
}) })
} }
r.Use(authenticator) 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")) w.Write([]byte("protected"))
}) })
}) })
// Public routes // Public routes
r.Group(func(r chi.Router) { 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")) w.Write([]byte("welcome"))
}) })
}) })