Alex Barlow
Alex Barlow

Reputation: 148

Golang 1.7 context value nil

I'm trying to implement a JWT (JSON web token) middleware using Go's 1.7 context package, but I'm running into a strange bug retrieving an earlier set context value..

Given the code..

func JWTAuthenticator(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        ctx := r.Context()
        jwtToken, _ := ctx.Value("jwt").(*jwt.Token)

        fmt.Printf("ctx = %+v\n", ctx)
        fmt.Printf("ctx = %+v\n", jwtToken)

        // Token is authenticated, pass it through
        next.ServeHTTP(w, r)
    })
}

This returns ..

context.Background.WithValue(&http.contextKey{name:"http-server"}, &http.Server{Addr:":8080", Handler:(*chi.Mux)(0xc4201ec180), ReadTimeout:0, WriteTimeout:0, TLSConfig:(*tls.Config)(0xc420210000), MaxHeaderBytes:0, TLSNextProto:map[string]func(*http.Server, *tls.Conn, http.Handler){"h2-14":(func(*http.Server, *tls.Conn, http.Handler))(0xb8410), "h2":(func(*http.Server, *tls.Conn, http.Handler))(0xb8410)}, ConnState:(func(net.Conn, http.ConnState))(nil), ErrorLog:(*log.Logger)(nil), disableKeepAlives:0, nextProtoOnce:sync.Once{m:sync.Mutex{state:0, sema:0x0}, done:0x1}, nextProtoErr:error(nil)}).WithValue(&http.contextKey{name:"local-addr"}, &net.TCPAddr{IP:net.IP{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, Port:8080, Zone:""}).WithCancel.WithCancel.WithValue(&chi.contextKey{name:"RouteContext"}, &chi.Context{URLParams:chi.params(nil), RoutePath:"", RoutePattern:"/store", RoutePatterns:[]string{"/store"}}).WithValue(0, "us2-ldn-barlow/XJoT7aahzI-000001").WithValue("jwt", &jwt.Token{Raw:"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdG9yZV9pZCI6NzA4MDJ9.eT70KOJbS4JJrsMC76KH4IPRozPt-ipjMDUSuAUhB4k", Method:(*jwt.SigningMethodHMAC)(0xc420133d80), Header:map[string]interface {}{"alg":"HS256", "typ":"JWT"}, Claims:map[string]interface {}{"store_id":70802}, Signature:"eT70KOJbS4JJrsMC76KH4IPRozPt-ipjMDUSuAUhB4k", Valid:true}).WithValue("jwt.err", <nil>)

ctx = <nil>

Which as you can does include a value .WithValue("jwt") but is returning nil!

Any ideas?

Upvotes: 2

Views: 2787

Answers (2)

Ali
Ali

Reputation: 19722

My problem was that the library the wrote to the context has a vendored copy of the shared library (that had keys in the context) and the main library also needed to vendor the same shared library to be able to look the values associated with thoee keys up,

As an alternative to using govendor or if you are using other vendoring methods ( I use gvt), you can just manually delete the copy that the vondored library has vendored inside of itself,

Upvotes: 0

Alex Barlow
Alex Barlow

Reputation: 148

I eventually found the issues.

The two types were the same jwt.Token however one type was from a vendored package in the imported library and one was from the package in my GOPATH. Although the same package and the type, Go had an issue casting and comparing these types!

To fix, I use a vendoring tool govendor and ran govendor add +external which mean that both packages now used the same import

Upvotes: 3

Related Questions