c# - 使用 PKCE 登录 Discord OAuth 的过程

标签 c# oauth discord.net

我正在尝试使用 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/

相关文章:

c# - 有没有一个WPF库可以绘制数学表达式?

java - 如何从 Fitbit Oauth 身份验证获取数据

swift - 带有 Dexcom API : get output frames failed, 状态 8196 的 OAuthSwift

c# - .NET Core - 有没有办法实现 WinForms?

discord - Discord token 的长度最近是否发生了变化?

c# - Discord bot 加入后立即离开语音 channel

c# - 如何让服务根据服务运行情况动态 Action

c# - 如果单个项目超出控件高度,WPF 列表框无法显示内容

c# - IdentityNotMappedException 异常

python - 使用 Python 3.4 的服务器到服务器应用程序的 OAuth 2.0,无法导入名称 'SERVICE_ACCOUNT'