编辑:澄清一下,获取授权码的工作如预期。这纯粹是将授权代码交换为令牌的步骤失败。
我试图用PKCE流实现授权代码,用于使用Spotify API进行身份验证。我知道有很多库可以实现这个功能,但我真的很想自己实现它。我说的流程是这样的: www.example.com 。但是,当我尝试将此代码交换为令牌时,我收到一个400 Bad Request,并显示消息“invalid client_secret”。这让我相信Spotify假设我正在尝试使用常规的授权代码流,因为客户端密钥根本不是PKCE流的一部分。我怀疑我对code_verifier或code_challenge的编码有误。我在SO(如何计算PCKE的code_verifier?)并将其翻译成C#,生成Base64编码的哈希值相同的结果,但它仍然不起作用。
下面是生成code_verifier和code_challenge的代码,以及请求交换代码的代码。
CodeVerifier:
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);
}
CodeChallenge:
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);
3条答案
按热度按时间w6lpcovy1#
我复制了代码,并能够使其工作。下面是Github上的一个工作项目:https://github.com/michaeldisaro/TestSpotifyPkce。
我所做的改变:
我在重定向到/authorize之前调用Init,在重定向URL上我有:
替换正确的正则表达式就可以完成这项工作。似乎问题出在“=”,只有最后一个必须替换。
这个函数并不完整,我只是看了一下内容变量,里面有一个令牌。拿着这个做你想做的事吧
2nbm6dog2#
下面是
GenerateNonce
(现在是GenerateCodeVerifier
)和GenerateCodeChallenge
的重构,它符合rfc-7636标准,集成到一个类中,既可以示例化,也可以用于静态方法。对于那些进入单元测试的人。
hec6srdp3#
另一个实现
这将为您提供从随机字符串计算出的code_challenge和code_verifier值。