我想测试我的OAuth2客户端,并对TokenURL端点使用模拟.模拟以ACCESS_TOKEN作为响应,但是总是有一个错误为missing access_token.

我用的是golang.org/x/oauth2和默认的围棋测试包.

我的模拟服务器:

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"

示例:我想刷新访问令牌

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

刷新令牌时出错:

oauth2: server response missing access_token

我已经判断过/试过了

  • 如果提供了Access_Token,则为模拟响应
  • OAuth2程序包的代码查看何时发生此错误,但尚未找到任何进一步信息
  • 已验证正确的配置参数(oauth2.Config.Endpoint t.TokenURL)

该代码与我的OAuth2提供程序一起运行,因此这只是一个测试问题.

谢谢!

推荐答案

您需要将Content-Type标头设置为application/json,以便客户端可以正确解释响应正文.

下面是一个完整的工作示例.

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

Go相关问答推荐

Golang Viper:如果第一个字段不存在,如何从另一个字段获取值

Golang中的泛型 struct /接口列表

JetBrains Goland,禁用突出显示测试文件

Docker 执行失败并显示cmd/ENTRYPOINT 中的命令未找到

如何解决构建Docker Compose时的权限被拒绝问题

Global Thread-local Storage 在 Go 中的可行性和最佳实践

缺少签名帮助文档

加密/椭圆:try 在无效点上进行操作

MQTT 客户端没有收到另一个客户端发送的消息

闭包所处的环境范围是什么?

如何使用泛型将接口转换为指定类型

Go 的垃圾收集器在使用时删除 ZeroMQ 套接字

使用 package`regexp` 查找 Golang 中的所有 mactch 子字符串,但得到意外结果

如何使用特定的 Go 版本运行 govulncheck?

如何在没有内存分配的情况下压缩和发布文件

GoLang 遍历 yaml 文件

为什么我不能使用来自 gocloak 中 Login() 的访问令牌在 KeyCloak 中创建新客户端?

将 CSVExport 函数传递给处理程序 Gin

函数的递归调用以 goroutine 和惯用方式开始,以在所有工作 goroutine 完成时继续调用者

如何使用 httputil.ReverseProxy 设置 X-Forwarded-For