我正在尝试使用 PKCE 将 Discord OAuth 添加到移动应用程序。我能够成功使用 DiscordAPI 进行身份验证,并且收到从服务器返回的代码
。
但是,当我尝试调用 https://discordapp.com/api/oauth2/token
端点时,我不断收到错误请求
结果。
我尝试了几种方法来获取我的 token ,但都失败了。
使用 HttpClient 的尝试 (1):
var nvc = new List<KeyValuePair<string, string>>();
nvc.Add(new KeyValuePair<string, string>("client_id", Constants.ClientId));
nvc.Add(new KeyValuePair<string, string>("client_secret", Constants.Secret));
nvc.Add(new KeyValuePair<string, string>("code_verifier", codeVerifier)); // method param
nvc.Add(new KeyValuePair<string, string>("grant_type", "authorization_code"));
nvc.Add(new KeyValuePair<string, string>("code", authCode)); // method param
nvc.Add(new KeyValuePair<string, string>("redirect_uri", Constants.Redirect));
nvc.Add(new KeyValuePair<string, string>("scope", "identify email connections"));
var req = new HttpRequestMessage(HttpMethod.Post, "https://discordapp.com/api/oauth2/token")
{
Content = new FormUrlEncodedContent(nvc)
};
var authTokenResponse = await this.Client.SendAsync(req).ConfigureAwait(false);
// results in BadRequest
我还尝试过使用像这样的 StringContent
对象:
var stringContent = new StringContent($"grant_type=authorization_code&client_id={Constants.ClientId}&client_secret={Constants.Secret}&code_verifier={codeVerifier}&code={authCode}&redirect_uri={Constants.Redirect}&scopes=identify%20email%20connections", Encoding.UTF8, "application/x-www-form-urlencoded");
这两种情况都会导致错误请求
使用 RestSharp 的尝试 (2)
var client = new RestSharp.RestClient($"{this.Client.BaseAddress}/oauth2/token");
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/x-www-form-urlencoded");
request.AddParameter("application/x-www-form-urlencoded", $"grant_type=authorization_code&client_id={Constants.ClientId}&client_secret={Constants.Secret}&code_verifier={code}&code={authCode}&redirect_uri={Constants.Redirect}&scopes=identify%20email%20connections", ParameterType.RequestBody);
var response = await client.ExecuteAsync(request);
我仔细检查了所有值,并确保我的客户端 ID 和密码正确。我尝试过使用和不使用 code_verifier
发送请求。如果没有code_verifier
,我会得到未经授权
。
问题
我应该如何修改我的 HttpClient 请求才能成功获得我的身份验证 token ?
更多信息:
为了遵守 PKCE,我需要一个 code_verifier
。这就是我生成代码的方式。 (请注意,我不尝试使用它作为身份验证代码。)
Random rng = new Random();
byte[] code = new byte[32];
rng.NextBytes(code);
CodeVerifier = Base64UrlEncoder.Encode(rng.ToString());
然后我使用借自 c-sharpcorner.com 的哈希算法,看起来像这样:
using (SHA256 sha256Hash = SHA256.Create())
{
// ComputeHash - returns byte array
var bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData));
// Convert byte array to a string
var builder = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
builder.Append(bytes[i].ToString("x2"));
}
return builder.ToString();
}
在获取我的授权代码时,我将结果作为我的 code_challenge
传递。
这是我了解到需要 PKCE 的地方。
https://github.com/discordapp/discord-api-docs/issues/450
PKCE 讨论在此继续:
https://github.com/discordapp/discord-api-docs/issues/1296
更新:
好吧,就这样了iwokal's回答,我重新阅读了上面链接的帖子,因此如果您使用自定义方案重定向
,则仅“需要”PKCE,如果您仅使用http
重定向将 code_verifier
去掉,就可以开始了。
也就是说,这个PKCE 工作流程没有记录。由于我花费了 500 积分,因此我会将积分奖励给能够解决 PKCE OAuth 工作流程的人。
您可以从头开始制定解决方案,我将对其进行测试。
最佳答案
好吧,经过一些研究,我可能知道发生了什么。您是否试图通过您创建的授权代码获取基于 token ?
我认为正确的方法是发送https://discordapp.com/api/oauth2/authorize请求将重定向到提供的 url,其中查询字符串包含正确的身份验证代码。
您应该在获取 token 的步骤中使用此代码。
我不知道这是否会改变任何东西,但我相信根据文档,没有“范围”这样的参数,它应该是“范围”。
关于c# - 使用 PKCE 登录 Discord OAuth 的过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60245469/