【发布时间】:2020-05-12 19:14:12
【问题描述】:
我正在使用 golang 来实现针对 Okta 的 PKCE 身份验证流程。 Okta 需要至少 43 个字符的 url 安全字符串(验证者),然后计算 sha256 哈希,以 base64 URL 编码(质询)发送。 Okta PKCE Flow
我生成一个随机验证器。这是一个示例:aAOzSsxfONaAauKYKRABWUfZLFgVFZqgbJRaArwKAzhzEWurUAhDyzcTkSKLClFL
生成base64编码的sha256和:
hasher := sha256.New()
hasher.Write([]byte(login.CodeVerifier))
codeChallenge := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
当给定上面的示例verifier 时产生了一个挑战:1XvaG5_-p9OPfxH9yeLmSWu5zGHxW6Pjq_HrdSsI-kk=
然而,在完成对/token 端点的 POST 后,总是返回错误:
{
"error": "invalid_grant",
"error_description": "PKCE verification failed."
}
这是 POST 到 /token 的逻辑:
code := r.URL.Query().Get("code")
state := r.URL.Query().Get("state")
log.Debug().Msgf("callback code:%s state:%s verifier:%s", code, state, loginCache[state])
values := url.Values{}
values.Set("grant_type", "authorization_code")
values.Set("client_id", clientID)
values.Set("redirect_uri", redirectURI)
values.Set("code", code)
values.Set("code_verifier", loginCache[state])
request, _ := http.NewRequest("POST", oktaTokenURL, strings.NewReader(values.Encode()))
request.URL.RawQuery = values.Encode()
request.Header.Set("accept", "application/json")
request.Header.Set("cache-control", "no-cache")
request.Header.Set("content-type", "application/x-www-form-urlencoded")
response, err := http.DefaultClient.Do(request)
【问题讨论】:
-
程序将
values编码为请求正文和请求查询字符串。两者都需要吗?这可能会导致问题吗? -
另外:创建请求后不要修改 URL(虽然这可能完全没问题,但它很丑陋。或者可能是错误的。)
-
request.URL.RawQuery = values.Encode()不应该在那里。作为 POST,不应该有查询字符串值。但是,删除该行并不会更改错误消息。