OAuth 2.0 应用实现

*此内容使用人工智能(Beta)翻译,可能包含错误。若要查看英文页面,请点按 此处

开放云支持具有或没有 PKCE 的 OAuth 2.0 授权流程,取决于您的客户是否机密或公开。

  • 机密客户端 是能够保密保密的应用程序,例如一个网站,可以在其后端安全存储并检索秘密。
  • 公共客户端是那些无法保守秘密的应用程序,例如移动和网页浏览器应用程序。

我们建议使用 PKCE 与 OAuth 2.0 授权代码流程对所有客户端进行授权,并对公共客户端进行要求。

要实现授权代码流程,您的应用执行以下步骤:

  1. 生成代码验证器和代码挑战(仅限 PKCE)。这允许您在请求中包含挑战而不是客户秘密,从而提高安全性。
  2. 向授权端发送 GET 请求,带有适当的参数。
  3. 处理授权回调。获得授权后,在重定向请求到您在应用创作品期间指定的 URL 时使用 Roblox 的授权代码。解析授权代码以供稍后使用。
  4. 向代币端点发送 POST 请求,带有授权代验证码。如果成功,您将收到用于发出 API 调用的访问和刷新代币。
  5. 调用任何支持 OAuth 2.0 认证的开放云 API,根据资源的参考文档访问您想要1) 使用权 2)通行证 3)访问权限问的资源。

以下部分进一步描述每个步骤。

生成代码挑战(仅限 PKCE)

在启动授权过程之前,您需要从代码验证器生成代码挑战。您可以使用您选择的编程语言中的库或内置函数来创建代码验证器、计算哈希值并进行 Base64 编码以生成代码挑战。

创建代码验证器时,只使用未保留的字符,包括大/小写字母(A-Z,a-z)、十进制数字(0-9)、撇号(-)、时间(.)、下划线(_)和撇号(~),最短长度为 43 个字符,最长长度为 128 个字符。

以下示例显示了如何使用 JavaScript 创建代码验证器并使用 SHA-256 散列算法生成代码挑战:

Generate Code Challenge

const crypto = require('crypto');
// base64URL encode the verifier and challenge
function base64URLEncode(str) {
return str.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
// create sha256 hash from code verifier
function sha256(buffer) {
return crypto.createHash('sha256').update(buffer).digest(`base64`);
}
// create a random code verifier
var code_verifier = base64URLEncode(crypto.randomBytes(32));
// generate a challenge from the code verifier
var code_challenge = base64URLEncode(sha256(code_verifier));

对于 PKCE,您需要在后续步骤中使用代码验证器和挑战值。

构建授权 URL

要启动用户权限验证过程,构建一个带有所需参数的权限 URL:

  • client_id : 您的App用的客户端ID在注册您的应用后获得。
  • redirect_uri : 您应App的重定向 URI,您应App的重新入口点。
  • scope : 请求的范围,定义了你应用程序在空间分隔列表中需要的访问权限。
  • response_type : 将其设置为 code 以指示授权代码流。 仅对PKCE需要
  • code_challenge : 从代码验证器生成的代码挑战。
  • code_challenge_method : 将此参数值设置为 S256 以表示代码挑战使用了 SHA-256 算法转换,这是最广泛支持和最安全的代码挑战方法。
  • state : 不透明的、安全的随机值,用于保持请求和回调之间的状态。 仅对非PKCE需要
  • client_secret : 您的App用的客户秘密在注册完成后获得 注册您的应用 .如果您使用 PKCE 进行身份验证,请忽略此参数。您的授权请求 URL 必须格式化良好,如以下示例:
PKCE 授权 URL 示例

https://apis.roblox.com/oauth/v1/authorize?client_id=7290610391231237934964
&code_challenge=PLEKKVCjdD1V_07wOKlAm7P02NC-LZ_1hQfdu5XSXEI
&code_challenge_method=S256
&redirect_uri=https://example.com/redirect
&scope=openid%20profile
&response_type=code
&state=abc123

当用户访问 URL 时,他们会经过授权流程。 如果成功,Roblox 将用户重定向到指定的 redirect_uri

处理权限授权回调

当授权流程成功时,您的应用程序在 GET 指定的 Roblox 授权服务器收到一个 redirect_uri 请求。在请求中,你收到 code (授权验证码) 和 state (如果你之前提供了值) 参数。

  • code 参数包含一个授权代码,应用程序可以从授权服务器交换获得访问代币。大多数后端服务器语言都有标准方式来访问查询参数作为解码的对象。你需要获取 code 参数并使用它来交换访问代币。

  • state 参数是你最初在授权请求中提供的不透明值。您可以使用此参数来维护授权过程的状态或上下文。

例如,如果你指定你的重定向 URI 为 https://example.com/redirect,你可能会收到以下 URL 的 GET 请求。

示例重定向 URL

https://example.com/redirect?code=10c45PNuquKnFJ6pUcy5-fHkghEM6lSegm-7hj9mVEprub1dSDuStuKK_EAUXY7AHTD63xcnmvxSLthp-C8g3jzIGZVzuXSd20Y2dEYI9hx0LZmPg95ME4z2K03UheiZbroyXUjYyB3ReoMqobzDVPzyx6IS8kj2Uu-11Xq_0JiTYxtDatuqXRNIAmJT8gMJmbSyOLOP_vnDvbeMUiBsqCRrkTGVbWSwYSc8sTVVE-535kYdqQOgNjH1ffCoZLGl8YYxLnpb2CXJlRQPrcjkA&state=6789

如果授权失败,您的应用程序收到了 GET 要指定重定向 URL 的 errorerror_descriptionstate (如果适用) 参数的请求。

  • error 参数指示在授权过程中发生的特定 OAuth 2.0 错误。
  • error_description 参数提供额外的错误细节。
  • state 参数可以帮助您的应用在出现故障时保持状态。

用授权代码交换访问代币

当你解析了授权 code 时,将其兑换为代币以访问所需的 Roblox 资源:

  1. 发送 POST 请求到 代币交换端点 ,请求一个访问代币和刷新代币。请求必须包含授权代验证码、客户端ID和代码验证值(PKCE)或客户端秘密(非PKCE)在 x-www-form-urlencoded 格式中。

  2. 从收到的响应中解析适用的代币。访问代币有效期为 15 分钟。将刷新代币安全地存储在服务器端,通常在服务器端,以便您将其用于以后获得新代币。

    示例代币终端响应

    {
    "access_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6IlBOeHhpb2JFNE8zbGhQUUlUZG9QQ3FCTE81amh3aXZFS1pHOWhfTGJNOWMiLCJ0eXAiOiJKV11234.eyJzdWIiOiIyMDY3MjQzOTU5IiwiYWlkIjoiM2Q2MWU3NDctM2ExNS00NTE4LWJiNDEtMWU3M2VhNDUyZWIwIiwic2NvcGUiOiJvcGVuaWQ6cmVhZCBwcm9maWxlOnJlYWQiLCJqdGkiOiJBVC5QbmFWVHpJU3k2YkI5TG5QYnZpTCIsIm5iZiI6MTY5MTYzOTY5OCwiZXhwIjoxNjkxNjQwNTk4LCJpYXQiOjE2OTE2Mzk2OTgsImlzcyI6Imh0dHBzOi8vYXBpcy5yb2Jsb3guY29tL29hdXRoLyIsImF1ZCI6IjcyOTA2MTAzOTc5ODc5MzQ5Nj1234.BjwMkC8Q5a_iP1Q5Th8FrS7ntioAollv_zW9mprF1ats9CD2axCvupZydVzYphzQ8TawunnYXp0Xe8k0t8ithg",
    "refresh_token": "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwia2lkIjoidGpHd1BHaURDWkprZEZkREg1dFZ5emVzRWQyQ0o1NDgtUi1Ya1J1TTBBRSIsInR5cCI6IkpXVCJ9..nKYZvjvXH6msDG8Udluuuw.PwP-_HJIjrgYdY-gMR0Q3cabNwIbmItcMEQHx5r7qStVVa5l4CbrKwJvjY-w9xZ9VFb6P70WmXndNifnio5BPZmivW5QkJgv5_sxLoCwsqB1bmEkz2nFF4ANLzQLCQMvQwgXHPMfCK-lclpVEwnHk4kemrCFOvfuH4qJ1V0Q0j0WjsSU026M67zMaFrrhSKwQh-SzhmXejhKJOjhNfY9hAmeS-LsLLdszAq_JyN7fIvZl1fWDnER_CeDAbQDj5K5ECNOHAQ3RemQ2dADVlc07VEt2KpSqUlHlq3rcaIcNRHCue4GfbCc1lZwQsALbM1aSIzF68klXs1Cj_ZmXxOSOyHxwmbQCHwY7aa16f3VEJzCYa6m0m5U_oHy84iQzsC-_JvBaeFCachrLWmFY818S-nH5fCIORdYgc4s7Fj5HdULnnVwiKeQLKSaYsfneHtqwOc_ux2QYv6Cv6Xn04tkB2TEsuZ7dFwPI-Hw2O30vCzLTcZ-Fl08ER0J0hhq4ep7B641IOnPpMZ1m0gpJJRPbHX_ooqHol9zHZ0gcLKMdYy1wUgsmn_nK_THK3m0RmENXNtepyLw_tSd5vqqIWZ5NFglKSqVnbomEkxneEJRgoFhBGMZiR-3FXMaVryUjq-N.Q_t4NGxTUSMsLVEppkTu0Q6rwt2rKJfFGuvy3s12345",
    "token_type": "Bearer",
    "expires_in": 899,
    "id_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6IkNWWDU1Mi1zeWh4Y1VGdW5vNktScmtReFB1eW15YTRQVllodWdsd3hnNzgiLCJ0eXAiOiJKV11234.eyJzdWIiOiIyMDY3MjQzOTU5IiwibmFtZSI6ImxpbmtzZ29hdCIsIm5pY2tuYW1lIjoibGlua3Nnb2F0IiwicHJlZmVycmVkX3VzZXJuYW1lIjoibGlua3Nnb2F0IiwiY3JlYXRlZF9hdCI6MTYwNzM1NDIzMiwicHJvZmlsZSI6Imh0dHBzOi8vd3d3LnJvYmxveC5jb20vdXNlcnMvMjA2NzI0Mzk1OS9wcm9maWxlIiwibm9uY2UiOiIxMjM0NSIsImp0aSI6IklELnltd3ZjTUdpOVg4azkyNm9qd1I5IiwibmJmIjoxNjkxNjM5Njk4LCJleHAiOjE2OTE2NzU2OTgsImlhdCI6MTY5MTYzOTY5OCwiaXNzIjoiaHR0cHM6Ly9hcGlzLnJvYmxveC5jb20vb2F1dGgvIiwiYXVkIjoiNzI5MDYxMDM5Nzk4NzkzNDk2NCJ9.kZgCMJQGsariwCi8HqsUadUBMM8ZOmf_IPDoWyQY9gVX4Kx3PubDz-Q6MvZ9eU5spNFz0-PEH-G2WSvq2ljDyg",
    "scope": "openid profile"
    }

向资源方法发出调用

现在你有了所需的访问代币,你可以使用它来向资源方法发出认证的调用。包含访问代币在所有 API 请求的头部中,以授权它们。

例如,您可以通过走过整个权限流程来测试您的应用程序是否正常运行,然后使用访问代币向 GET 发出一个 请求 > 。确保在调用此端点之前,您拥有 openidopenidprofile 范围。如果成功,那个端点的响应看起来像这样:

示例用户信息响应

{
"sub": "12345678",
"name": "Jane Doe",
"nickname": "robloxjanedoe",
"preferred_username": "robloxjanedoe",
"created_at": 1607354232,
"profile": "https://www.roblox.com/users/12345678/profile”
}