【发布时间】:2021-03-18 01:35:26
【问题描述】:
编辑:澄清一下,获取授权码按预期工作。这纯粹是用授权码交换失败的令牌的步骤。
我正在尝试使用 PKCE 流程实现授权代码,以使用 spotify API 进行身份验证。我知道那里有图书馆,但我真的很想自己实现它。我说的流程是这样的: https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow-with-proof-key-for-code-exchange-pkce 我能够制作链接以将用户重定向到同意页面并获取授权码。但是,当我尝试将此代码交换为令牌时,我收到 400 错误请求,并显示消息“invalid client_secret”。这让我相信 Spotify 假设我正在尝试使用常规授权代码流,因为客户端密码根本不是 PKCE 流的一部分。我怀疑我对 code_verifier 或 code_challenge 的编码错误。 我在 SO (How to calculate PCKE's code_verifier?) 上找到了这个答案并将其翻译成 C#,得到了与 Base64 编码哈希相同的结果,但它仍然不起作用。
下面是我生成 code_verifier 和 code_challenge 的代码,以及请求交换代码的代码。
代码验证器:
private string GenerateNonce()
{
const string chars = "abcdefghijklmnopqrstuvwxyz123456789";
var random = new Random();
var nonce = new char[100];
for (int i = 0; i < nonce.Length; i++)
{
nonce[i] = chars[random.Next(chars.Length)];
}
return new string(nonce);
}
代码挑战:
private string GenerateCodeChallenge(string codeVerifier)
{
using var sha256 = SHA256.Create();
var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
return Convert.ToBase64String(hash).Replace("+/", "-_").Replace("=", "");
}
兑换代币:
var parameters = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("client_id", ClientId ),
new KeyValuePair<string, string>("grant_type", "authorization_code"),
new KeyValuePair<string, string>("code", authCode),
new KeyValuePair<string, string>("redirect_uri", "http://localhost:5000"),
new KeyValuePair<string, string>("code_verifier", codeVerifier)
};
var content = new FormUrlEncodedContent(parameters );
var response = await HttpClient.PostAsync($"https://accounts.spotify.com/api/token", content);
【问题讨论】:
-
嗨,我想你错过了一步。在调用 /api/token 之前,您应该调用 /authorize 以获取与访问令牌交换的代码。
-
@Michaelsoft 抱歉,如果不清楚 - 我检索授权代码的部分工作正常,我也在请求内容中传递它,如“交换令牌”下方的代码所示" 帖子中的标题。
-
好的,对不起,我误解了那部分。您是否尝试过类似的东西而不是 PostAsync? var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, url) { Content = new FormUrlEncodedContent(parameters) }; var res = await client.SendAsync(req);
-
也许使用字典而不是 List
>? -
感谢您的意见 - 我现在已经尝试了这两种方法,但不幸的是都没有成功。我几乎 100% 确定它一定与我如何编码 code_verifier 或 code_challenge 有关,但我不知道是什么
标签: c# oauth-2.0 oauth spotify