【问题标题】:Discord OAuth Code UsageDiscord OAuth 代码使用
【发布时间】:2017-09-01 19:14:03
【问题描述】:

我对使用 Discord API 与 Discord 交互感兴趣。我会将他们的文档描述为“稀疏”,但也许我只是没有找对地方。我的大部分信息来自这个页面:

https://discordapp.com/developers/docs/topics/oauth2

我已经设置了我的 Discord 公会和应用程序(甚至是机器人,这可能是不必要的)。我的具体计划是允许用户授予我的站点权限以将他们添加到私人 Discord 公会/服务器。我的网站页面中有一个引用此 URL 的超链接:

https://discordapp.com/api/oauth2/authorize?client_id=[ClientID]&scope=guilds.join&response_type=code&redirect_uri=[RedirectURI]

这部分似乎运作良好。用户批准请求。然后,用户将在查询字符串中使用“代码”键值对发送回我的站点。我认为这个代码就是所谓的“授权代码”。那么如何使用此授权码将用户添加到我的公会?我在 Discord 网站上找到了这个页面:

https://discordapp.com/developers/docs/resources/guild#add-guild-member

从该页面我可以看到我需要向该 URL 发起 PUT:

https://discordapp.com/api/guilds/{guild.id}/members/{user.id}

但我不知道 {user.id}。我只有一个授权码。

它还说,“...前提是您拥有 guilds.join 范围内的用户的有效 oauth2 访问令牌。”我没有访问令牌。同样,我只有一个授权码。

所以在我看来,我需要以某种方式将此授权代码交换为访问令牌和用户 ID。有人可以告诉我该怎么做吗?我一直在试验以下网址,但不知道用什么方法(GET、POST 等)或发送什么参数:

https://discordapp.com/api/oauth2/token

因为我想了解它是如何工作的,所以我更愿意知道如何使用普通的 Web 请求(例如 HttpWebRequest 和 WebClient,而不是使用一些 OAuth 库)来做到这一点。

更新

我决定(选择性地)阅读这个 RFC:

https://www.rfc-editor.org/rfc/rfc6749#section-4.1.3

我已经链接了我认为最合适的部分。似乎正确的程序是向以下 URL 和参数发送 POST 请求:

https://discordapp.com/api/oauth2/token

grant_type=authorization_code&code=[AuthorizationCode]&redirect_uri=[RedirectURI]&client_id=[ClientID]

这似乎也符合 Peter G 的回答。不幸的是,此请求失败并出现 401(未经授权)错误。所以我认为这是一个死胡同。我已经尝试了几次,但希望有一个解决方案。我收到了这个回复正文:

{"error": "invalid_client"}

我收到了这些标题:

连接:关闭

编译指示:无缓存

严格的传输安全性:max-age=31536000;包含子域

Alt-Svc:清除

CF-RAY:[RedactedJustInCase]

内容长度:27

缓存控制:无存储

内容类型:application/json

日期:格林威治标准时间 2017 年 4 月 7 日星期五 01:12:19

Set-Cookie: __cfduid=[RedactedJustInCase]; expires=18 年 4 月 7 日星期六 格林威治标准时间 01:12:19;路径=/;域=.discordapp.com; HttpOnly

服务器:cloudflare-nginx

通过:1.1 谷歌

【问题讨论】:

    标签: c# oauth oauth-2.0 httpwebrequest discord


    【解决方案1】:

    就获取 OAuth 令牌而言,您几乎已经完成了。您只需要使用您链接的文档中列出的另一个 URL,https://discordapp.com/api/oauth2/token。使用以下参数 POST 到它:https://discordapp.com/api/oauth2/token?client_id=[ClientID]&grant_type=authorization_code&code=[AuthorizationCode]&redirect_uri=[RedirectURI]&client_secret=[Secret] 其中AuthorizationCode 是第一个 URL 的返回值,Secret 是您首次注册应用时获得的客户端密码。

    这应该让您在响应正文中返回客户端令牌(以及令牌过期需要多长时间)。至于获取用户对象,您需要在第一个请求中添加范围identify,以便您可以使用令牌调用https://discordapp.com/developers/docs/resources/user#get-current-user(如果链接断开,则为GET users/@me)。该 API 将以 JSON 形式返回 User 对象。

    最后,您可以使用刚刚获得的用户对象,通过 PUT-ing 到 https://discordapp.com/api/guilds/[guild.id]/members/[user.id] 来添加用户。

    在获取客户端令牌后使用API​​(获取用户对象并将用户放入公会的API)时,您需要使用Bearer auth方案将令牌放在授权标头下的HTTP请求中。基本上,这意味着标题应该设置为"Bearer TOKEN_HERE"。如果您还没有使用它,还应该使用内容类型“application/x-www-form-urlencoded”。

    如果您在这里有什么不明白的地方,我强烈建议您阅读源 RFC 中有关 oauth 的内容(不用担心,这两部分很短):getting an auth codegetting a tokenauthenticating with Bearer scheme。当您不使用库时,它们就是休息时间。

    【讨论】:

    • 彼得 G,谢谢您的回答。它在很大程度上与我今天发布问题后进行的实验相匹配。我不怀疑你的回答是正确的,但由于某种原因,它不起作用。请参阅我在上面所做的更新。我希望你会知道我得到了什么“invalid_client”。谢谢。
    • 我刚刚意识到除了客户端 ID 之外,Discord 还有一个客户端密码。当您第一次注册您的应用程序时,您应该会得到它。尝试将 &client_secret=[Secret] 添加到给您带来麻烦的 URL 并告诉我会发生什么。
    • 我有信心我已经尝试过,但我想我没有。有效!谢谢你。我会接受你的回答。您可能还想在答案中包含 client_secret 部分,因为这是我缺少的关键信息。再次感谢!
    • 是的,只是想在我编辑之前确保它工作正常。
    • 您的回答也帮助我获得了当前用户,非常感谢。但我坚持添加公会成员。我已经开始了一个新问题,希望您能提供帮助:stackoverflow.com/q/43269517/1325179。谢谢。
    猜你喜欢
    • 2021-04-12
    • 2019-04-22
    • 2020-05-31
    • 1970-01-01
    • 2019-12-17
    • 1970-01-01
    • 2018-05-31
    • 2022-10-21
    • 2013-03-03
    相关资源
    最近更新 更多