diff --git a/README.md b/README.md index afbb05a..5aed9cb 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ func main() { Auth: authFunc, Claims: claimsFunc, } - j, err := jwt.NewMiddleware(config) + j, err := jwt.New(config) if err != nil { panic(err) } @@ -93,10 +93,10 @@ config := &jwt.Config{ Auth: authFunc, // func(string, string) error Claims: claimsFunc, // func(string) (map[string]interface{}) } -j, err := jwt.NewMiddleware(config) +j, err := jwt.New(config) ``` -Once the middleware is instanciated, create a route for users to generate a JWT +Once the middleware is instantiated, create a route for users to generate a JWT at. ```go diff --git a/examples/net-http.go b/examples/net-http.go index d664040..9c1b37d 100644 --- a/examples/net-http.go +++ b/examples/net-http.go @@ -44,7 +44,7 @@ func main() { Auth: authFunc, Claims: claimsFunc, } - j, err := jwt.NewMiddleware(config) + j, err := jwt.New(config) if err != nil { panic(err) } diff --git a/jwt.go b/jwt.go index 5fbcbd6..c75a2e3 100644 --- a/jwt.go +++ b/jwt.go @@ -17,6 +17,7 @@ const ( alg = "HS256" ) +// Errors introduced by this package. var ( ErrMissingConfig = errors.New("missing configuration") ErrMissingSecret = errors.New("please provide a shared secret") @@ -30,25 +31,33 @@ var ( ErrParsingCredentials = errors.New("error parsing credentials") ) +// Config is a container for setting up the JWT middleware. type Config struct { Secret string Auth AuthFunc Claims ClaimsFunc } +// AuthFunc is a type for delegating user authentication to the client-code. type AuthFunc func(string, string) error +// ClaimsFunc is a type for delegating claims generation to the client-code. type ClaimsFunc func(string) (map[string]interface{}, error) +// VerifyClaimsFunc is a type for for processing and validating JWT claims +// on one or more route's in the client-code. type VerifyClaimsFunc func([]byte) error -type JWTMiddleware struct { +// Middleware is where we store all the specifics related to the client's +// JWT needs. +type Middleware struct { secret string auth AuthFunc claims ClaimsFunc } -func NewMiddleware(c *Config) (*JWTMiddleware, error) { +// New creates a new Middleware from a user-specified configuration. +func New(c *Config) (*Middleware, error) { if c == nil { return nil, ErrMissingConfig } @@ -61,7 +70,7 @@ func NewMiddleware(c *Config) (*JWTMiddleware, error) { if c.Claims == nil { return nil, ErrMissingClaimsFunc } - m := &JWTMiddleware{ + m := &Middleware{ secret: c.Secret, auth: c.Auth, claims: c.Claims, @@ -69,7 +78,10 @@ func NewMiddleware(c *Config) (*JWTMiddleware, error) { return m, nil } -func (m *JWTMiddleware) Secure(h http.Handler, v VerifyClaimsFunc) http.Handler { +// Secure wraps a client-specified http.Handler with a verification function, +// as well as-built in parsing of the request's JWT. This allows each handler +// to have it's own verification/validation protocol. +func (m *Middleware) Secure(h http.Handler, v VerifyClaimsFunc) http.Handler { secureHandler := func(w http.ResponseWriter, r *http.Request) *jwtError { authHeader := r.Header.Get("Authorization") if authHeader == "" { @@ -144,7 +156,10 @@ func (m *JWTMiddleware) Secure(h http.Handler, v VerifyClaimsFunc) http.Handler return errorHandler(secureHandler) } -func (m *JWTMiddleware) GenerateToken() http.Handler { +// GenerateToken returns a middleware that parsing an incoming request for a JWT, +// calls the client-supplied auth function, and if successful, returns a JWT to +// the requester. +func (m *Middleware) GenerateToken() http.Handler { generateHandler := func(w http.ResponseWriter, r *http.Request) *jwtError { var b map[string]string err := json.NewDecoder(r.Body).Decode(&b) @@ -184,7 +199,7 @@ func (m *JWTMiddleware) GenerateToken() http.Handler { } } - claimsJson, err := json.Marshal(claims) + claimsJSON, err := json.Marshal(claims) if err != nil { return &jwtError{ status: http.StatusInternalServerError, @@ -193,7 +208,7 @@ func (m *JWTMiddleware) GenerateToken() http.Handler { } } - claimsSet, err := encode(claimsJson) + claimsSet, err := encode(claimsJSON) if err != nil { return &jwtError{ status: http.StatusInternalServerError, diff --git a/jwt_test.go b/jwt_test.go index dafa1c1..c2ad4ba 100644 --- a/jwt_test.go +++ b/jwt_test.go @@ -48,21 +48,21 @@ var verifyClaimsFunc = func(claims []byte) error { return nil } -func newJWTMiddlewareOrFatal(t *testing.T) *JWTMiddleware { +func newMiddlewareOrFatal(t *testing.T) *Middleware { config := &Config{ Secret: "password", Auth: authFunc, Claims: claimsFunc, } - middleware, err := NewMiddleware(config) + middleware, err := New(config) if err != nil { t.Fatalf("new middleware: %v", err) } return middleware } -func newToken(t *testing.T) (string, *JWTMiddleware) { - middleware := newJWTMiddlewareOrFatal(t) +func newToken(t *testing.T) (string, *Middleware) { + middleware := newMiddlewareOrFatal(t) authBody := map[string]interface{}{ "email": "user@example.com", "password": "password", @@ -85,7 +85,7 @@ func newToken(t *testing.T) (string, *JWTMiddleware) { } func TestNewJWTMiddleware(t *testing.T) { - middleware := newJWTMiddlewareOrFatal(t) + middleware := newMiddlewareOrFatal(t) if middleware.secret != "password" { t.Errorf("wanted password, got %v", middleware.secret) } @@ -120,7 +120,7 @@ func TestNewJWTMiddlewareNoConfig(t *testing.T) { }: ErrMissingClaimsFunc, } for config, jwtErr := range cases { - _, err := NewMiddleware(config) + _, err := New(config) if err != jwtErr { t.Errorf("wanted error: %v, got error: %v using config: %v", jwtErr, err, config) } @@ -159,7 +159,7 @@ func TestGenerateTokenHandler(t *testing.T) { } func TestSecureHandlerNoToken(t *testing.T) { - middleware := newJWTMiddlewareOrFatal(t) + middleware := newMiddlewareOrFatal(t) resp := httptest.NewRecorder() req, _ := http.NewRequest("GET", "http://example.com", nil) middleware.Secure(testHandler, verifyClaimsFunc).ServeHTTP(resp, req) @@ -170,7 +170,7 @@ func TestSecureHandlerNoToken(t *testing.T) { } func TestSecureHandlerBadToken(t *testing.T) { - middleware := newJWTMiddlewareOrFatal(t) + middleware := newMiddlewareOrFatal(t) resp := httptest.NewRecorder() req, _ := http.NewRequest("GET", "http://example.com", nil) req.Header.Set("Authorization", "Bearer abcdefg")