auth0 / go-jwt-middleware

A Middleware for Go Programming Language to check for JWTs on HTTP requests
MIT License
1.08k stars 205 forks source link

Test handler that requires authentication #154

Closed jpmeijers closed 2 years ago

jpmeijers commented 2 years ago

I wanted to write tests for my handlers, but had the issue of my handlers requiring the auth0 decoded access token in the context. Some searching further and I managed to do the following to add the user id (subject field) to the context.

Maybe someone can help how one would add the other fields and custom claims. I have not yet been successful in adding custom claims to the context.

func TestHandler(t *testing.T) {

    // Create a request to pass to our handler. We don't have any query parameters for now, so we'll
    // pass 'nil' as the third parameter.
    req, err := http.NewRequest("GET", "/path", nil)
    if err != nil {
        t.Fatal(err)
    }

    // We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response.
    rr := httptest.NewRecorder()
    handler := http.HandlerFunc(MyHandlerFunction)

    // Populate the request's context with our test data.
    // ie. add the Auth0 claims
    ctx := req.Context()
    registeredClaims := validator.RegisteredClaims{Subject: "auth0|1158"}

    ctx = context.WithValue(ctx, jwtmiddleware.ContextKey{},
        &validator.ValidatedClaims{
            RegisteredClaims: registeredClaims,
            CustomClaims:     nil,
        },
    )

    // Add our context to the request: note that WithContext returns a copy of
    // the request, which we must assign.
    req = req.WithContext(ctx)

    // Our handlers satisfy http.Handler, so we can call their ServeHTTP method
    // directly and pass in our Request and ResponseRecorder.
    handler.ServeHTTP(rr, req)

    // Check the status code is what we expect.
    if status := rr.Code; status != http.StatusOK {
        t.Errorf("handler returned wrong status code: got %v want %v",
            status, http.StatusOK)
    }

    // Check the response body is what we expect.
    var responseJson interface{}
    err = json.Unmarshal(rr.Body.Bytes(), &responseJson)
    if err != nil {
        t.Fatalf(err.Error())
    }
    log.Println(utils.PrettyPrint(responseJson))
}
grounded042 commented 2 years ago

You should be able init the middleware and then do something like middleware.CheckJWT(MyHandlerFunction)

See this for examples of how we test things:

https://github.com/auth0/go-jwt-middleware/blob/master/middleware_test.go#L154

grounded042 commented 2 years ago

@jpmeijers I've opened a PR which shows some tests: https://github.com/auth0/go-jwt-middleware/pull/157

jpmeijers commented 2 years ago

Nice. I think it is clear enough and I'll be able to follow it to write my own tests.