2

I want to test my oauth2 client and use a mock for TokenURL endpoint. The mock responds with access_token but there is always an error with missing access_token.

I am using golang.org/x/oauth2 and default go testing package.

My mock server:

server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if r.URL.Path == "/token" {
            // Mock the token endpoint
            json.NewEncoder(w).Encode(struct {
                AccessToken  string    `json:"access_token"`
                TokenType    string    `json:"token_type"`
                RefreshToken string    `json:"refresh_token"`
                Expiry       time.Time `json:"expiry"`
            }{
                AccessToken:  "access-token",
                TokenType:    "Bearer",
                RefreshToken: "refresh-token",
                Expiry:       time.Now().Add(2 * time.Hour),
            })
        }
    }))
    defer server.Close()
    mockConfig.Endpoint.TokenURL = server.URL + "/token"

example: I want to refresh access token

tokenSource := a.config.TokenSource(ctx, &oauth2.Token{
            RefreshToken: session.RefreshToken,
        })

error while refreshing token:

oauth2: server response missing access_token

I have already checked/tried

  • the mock response, if access_token is given
  • the code of oauth2 package to see when this error occurs, but have not found any further information
  • verified the right config parameter (oauth2.Config.Endpoint.TokenURL)

The code is running with my oauth2 provider, so it is just a testing issue.

Thanks!

1 Answer 1

1

You need to set the Content-Type header to application/jsonso that the client can properly interpret the response body.

Here is a complete working example.

func MockOAuth2Server() *http.Server {
    mux := http.NewServeMux()
    mux.HandleFunc("/auth", func(w http.ResponseWriter, r *http.Request) {
        // Always redirect to the callback URL with a fixed code
        http.Redirect(w, r, r.URL.Query().Get("redirect_uri")+"?code=mockcode"+"&state="+r.URL.Query().Get("state"), http.StatusFound)
    })
    mux.HandleFunc("/token", func(w http.ResponseWriter, r *http.Request) {
        // Set the content type to JSON 
        w.Header().Set("Content-Type", "application/json")

        idToken, err := generateMockIDToken()
        if err != nil {
            slog.Error("Error generating mock id token", "error", err.Error())
        }
        w.Write([]byte(`{"access_token": "mocktoken", "id_token": "` + idToken + `", "token_type": "bearer"}`))
    })

    mux.HandleFunc("/introspect", func(w http.ResponseWriter, r *http.Request) {
        // Always return that the token is active
        w.Header().Set("Content-Type", "application/json")
        w.Write([]byte(`{"active": true}`))
    })
    return &http.Server{
        Addr:    "localhost:9999",
        Handler: mux,
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

thank you! The solution was too easy :-( I just added w.Header().Set("Content-Type", "application/json") before responding to request and it works

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.