SebastianWi
SebastianWi

Reputation: 43

golang.org/x/oauth2 oauth2.Config.Endpoint.TokenURL mock: missing access_token

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 code is running with my oauth2 provider, so it is just a testing issue.

Thanks!

Upvotes: 2

Views: 187

Answers (1)

adel
adel

Reputation: 764

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,
    }
}

Upvotes: 1

Related Questions