Skip to content

Commit

Permalink
Cover test from patch #10 with example.
Browse files Browse the repository at this point in the history
  • Loading branch information
pascaldekloe committed Dec 23, 2019
1 parent d3f3dbf commit de3720c
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 19 deletions.
29 changes: 29 additions & 0 deletions examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,35 @@ func ExampleHandler_deny() {
// Try expired token… HTTP 401 Bearer error="invalid_token", error_description="jwt: time constraints exceeded"
}

// Custom Response Format
func ExampleHandler_error() {
h := &jwt.Handler{
Keys: &jwt.KeyRegister{ECDSAs: []*ecdsa.PublicKey{&someECKey.PublicKey}},

// JSON messages instead of plain text
Error: func(w http.ResponseWriter, error string, statusCode int) {
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
w.WriteHeader(statusCode)
fmt.Fprintf(w, `{"msg": %q}`, error)
},
}

req := httptest.NewRequest("GET", "/had-something-for-this", nil)
var c jwt.Claims
c.Expires = jwt.NewNumericTime(time.Now().Add(-time.Second))
if err := c.ECDSASignHeader(req, jwt.ES512, someECKey); err != nil {
fmt.Println("sign error:", err)
}

resp := httptest.NewRecorder()
h.ServeHTTP(resp, req)
fmt.Println("HTTP", resp.Code, resp.Header().Get("WWW-Authenticate"))
fmt.Println(resp.Body)
// Output:
// HTTP 401 Bearer error="invalid_token", error_description="jwt: time constraints exceeded"
// {"msg": "jwt: time constraints exceeded"}
}

// Func As A Request Filter
func ExampleHandler_filter() {
h := &jwt.Handler{
Expand Down
34 changes: 15 additions & 19 deletions web.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,17 @@ type Handler struct {
// as a filter or as an extended http.HandlerFunc.
Func func(http.ResponseWriter, *http.Request, *Claims) (pass bool)

// WriteError allows for custom error responses. When nil it defaults to http.Error.
// The appropriate WWW-Authenticate header is already present on w.
WriteError func(w http.ResponseWriter, error string, code int)
// Error sends a custom response. Nil defaults to http.Error.
// The appropriate WWW-Authenticate value is already present.
Error func(w http.ResponseWriter, error string, statusCode int)
}

func (h *Handler) error(w http.ResponseWriter, error string, statusCode int) {
if h.Error != nil {
h.Error(w, error, statusCode)
} else {
http.Error(w, error, statusCode)
}
}

// ServeHTTP honors the http.Handler interface.
Expand All @@ -184,22 +192,14 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} else {
w.Header().Set("WWW-Authenticate", `Bearer error="invalid_token", error_description=`+strconv.QuoteToASCII(err.Error()))
}
if h.WriteError != nil {
h.WriteError(w, err.Error(), http.StatusUnauthorized)
return
}
http.Error(w, err.Error(), http.StatusUnauthorized)
h.error(w, err.Error(), http.StatusUnauthorized)
return
}

// verify time constraints
if !claims.Valid(time.Now()) {
w.Header().Set("WWW-Authenticate", `Bearer error="invalid_token", error_description="jwt: time constraints exceeded"`)
if h.WriteError != nil {
h.WriteError(w, "jwt: time constraints exceeded", http.StatusUnauthorized)
return
}
http.Error(w, "jwt: time constraints exceeded", http.StatusUnauthorized)
h.error(w, "jwt: time constraints exceeded", http.StatusUnauthorized)
return
}

Expand Down Expand Up @@ -227,11 +227,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if !ok {
msg := "jwt: want string for claim " + claimName
w.Header().Set("WWW-Authenticate", `Bearer error="invalid_token", error_description=`+strconv.QuoteToASCII(msg))
if h.WriteError != nil {
h.WriteError(w, msg, http.StatusUnauthorized)
return
}
http.Error(w, msg, http.StatusUnauthorized)
h.error(w, msg, http.StatusUnauthorized)
return
}

Expand All @@ -244,4 +240,4 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}

h.Target.ServeHTTP(w, r)
}
}

0 comments on commit de3720c

Please sign in to comment.