More namely, I need to throw a HTTP 403 back if the JWT verification anything but succeeds. How would you default to that?
The JWT verification works now. Here's my handler.
func (ma *myapp) SomeHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqToken := r.Header.Get("Authorization")
splitToken := strings.Split(reqToken, "Bearer ")
reqToken = splitToken[1] // It will crap out here, if there isn't an authorization header present
err := lib.VerifyIDToken(ma.fbapp, reqToken)
if err != nil {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
enc := json.NewEncoder(w)
enc.Encode(lib.MarketDataMap)
}
However, if you just go to the URL itself, it will throw a 502 bad gateway from nginx, because my Go app throws an index out of bounds error for reqToken = splitToken[1]
, which makes sense since nothing is there.
How would one default to http 403 in a handler, in best practice? I can't attach err
to the logic, before I am at VerifyIDToken
, and there, the index out of bounds has already happened.
Any input is appreciated! I'm rather new to Go, but finding it nicer and nicer the more I learn Definitely gonna be my Go...-to language from now on(Coming from Java)
评论:
seankhliao:
titpetric:if you need to do this for a lot of handlers you can wrap it in something like:
type precheck func(w http.ResponseWriter, r *http.Request) func (p precheck) ServeHTTP(w http.ResponseWriter, r *http.Request) { // verification here p(w, r) }
and use it like this:
http.Handle('/some/path/', precheck(someHandler))
cbll:You can check len(splitToken) to see if you have 2 items.
if len(splitToken) < 2 { http.Error(...) return } reqToken = splitToken[1] ...
titpetric:But, since this service only responds to valid requests with an authentication header + JWT, wouldn't it be "prettier" for it to return 403 for everything except successful requests? Or maybe I'm just dreaming :)
Redundancy_:Short answer: If you'd mask all bad requests to 403, you'll have a hard time tracking down the actual error. The 503 is a valid response, which you resolve by writing better code in this case. In another case it might indicate a database failure, or something else. Either way, it's something that should be investigated and corrected, and not hidden under the carpet ;)
cbll:a panic due to looking at a slice index that doesn't exist isn't pretty...
Alternatively, use empty values:
authorizationHeader := r.Header.Get("Authorization") var reqToken string const authPrefix = "Bearer " if strings.HasPrefix(authorizationHeader, authPrefix) { reqToken = authorizationHeader[len(authPrefix):] } err := lib.VerifyIDToken(ma.fbapp, reqToken) ...
Assuming that "" will fail happily in a non-side-effecty way, you could do that without breaking your control flow and basically make a missing auth token the same as a bad auth token.
Redundancy_:a panic due to looking at a slice index that doesn't exist isn't pretty...
Indeed, hence why I am learning :)!
Alternatively, use empty values:
Thought of this, but seemed a bit javascripty to me. But yeah looks a bit better in the flow, I can see that.
cbll:I feel like the better answer is /u/titpetric's with a proper test and early return, I'm just giving you some options.
Gotcha. Thanks for the help!
