为通过guilds.join作用域,Discord OAuth2.0添加到行会的用户赋予角色

时间:2019-07-26 18:12:26

标签: oauth-2.0 discord

我想在我的网站上集成Discord的OAuth2.0,这样我就可以将用户添加到行会中并赋予他们特定的角色。

我已经搜索过开发人员门户网站文档,但没有找到任何内容。

2 个答案:

答案 0 :(得分:0)

Discord Oauth实现在https://discordapp.com/developers/docs/topics/oauth2中进行了描述。您可能需要将其与RFC 6749一起阅读,以大致了解Oauth的工作原理。

您不仅需要Discord“应用程序”,而且此应用程序还需要一个您已加入相关公会(即“服务器”)的机器人帐户。机器人程序需要在公会中具有CREATE_INSTANT_INVITEMANAGE_ROLES权限,并且机器人程序帐户需要具有的角色比角色列表中的角色要高。分配给用户。另一方面,您不需要为此将机器人实际上连接到Discord Websocket网关。

步骤将是:

  1. 将用户发送到Discord的授权URL ,使用查询参数标识您的应用程序,并请求identifyguilds.join范围。

  2. 如果用户正确识别并批准了请求,则其浏览器最终将重定向到您选择的指向后端服务器的URL。该URL作为授权URL中的参数提供,必须预先在应用程序控制面板中列入白名单。

    常见错误:重定向URL必须与列入白名单的URL 字符匹配。仅仅一个作为另一个的前缀是不够的。

    当您收到重定向后,是时候检查(使用会话cookie或您正在使用的任何东西)该用户是您要添加到公会中的用户了,

  3. Discord将某些查询字符串添加到重定向URL,您的后端可使用这些查询字符串来构建Discord的令牌交换请求。在此请求中,您提供应用程序的秘密凭据以及重定向中的密码 code ,并获得一个 bearer令牌,该令牌表示应用程序和权利的组合您是从该特定用户那里获得的。

    常见错误:令牌交换请求的参数之一必须是原始重定向URL。这必须与您在第1步中使用的URL 相同。即使您的应用程序将 白名单也列出了其他URL,也不能是其他URL!

    常见错误:令牌交换请求的大多数参数都放在POST正文中,该正文必须以application/x-www-form-urlencoded格式编码。有时人们使用HTTP堆栈,默认情况下会将其数据编码为JSON,并且感到困惑,这是行不通的。如果您发送的实际数据已序列化为JSON,则无法将application/x-www-form-urlencoded放在Content-Type标头中。

    注意事项:您可能会发现一些代码示例,这些示例试图在URL中而不是POST正文中提供令牌交换参数作为查询参数。不和谐的曾经接受了,但现在不再了。

  4. 发出一个Get current user请求,该请求已通过令牌交换中获得的承载者令牌进行了身份验证。这会给您您正在与之交谈的用户的Discord ID。

  5. 您现在拥有发出Add guild member请求所需要的信息,该请求已通过已认证并带有固定的 bot令牌并且包含用于PUT正文中用户的 bearer令牌,这次必须为JSON。您可以使用可选的roles参数来设置新成员开始使用的角色。

    常见错误:这应该是一个PUT请求,而不是POST。

我假设您硬编码(或配置)您正在管理的行会的ID和要分配的角色。

请注意,即使Discord ID是(64位)整数,也应在JSON主体中将它们序列化为 strings ,以便与JavaScript之类的语言兼容,这些语言本来就不支持这么大的整数

(有关第4步和第5步的身份验证的详细信息,请参见https://discordapp.com/developers/docs/reference#authentication

答案 1 :(得分:0)

从 oauth 获取访问令牌并与我一样。
Discord Api - Add Guild Member

await axios({
method: 'PUT',
    url: `https://discord.com/api/guilds/${process.env.SERVER_ID}/members/${profile.id}`,
    headers: {
        'Authorization': `Bot ${process.env.CLIENT_TOKEN}`,
        'Content-type': 'application/json'
    },
    data: {
        'access_token': `${accessToken}`
    }
}).then().catch(err => {})