mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-24 06:34:09 +00:00
update rules
This commit is contained in:
parent
4c390fdd37
commit
d5522b2fef
8549 changed files with 11783 additions and 1888 deletions
241
.cursor/rules/roblox/en-us/cloud/auth/api-keys.md
Normal file
241
.cursor/rules/roblox/en-us/cloud/auth/api-keys.md
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
---
|
||||
title: Manage API keys
|
||||
description: Explains how to create API keys and add permissions to use Open Cloud web APIs for your experience.
|
||||
---
|
||||
|
||||
Open Cloud authenticates and authorizes API access with the use of API keys,
|
||||
which allow you to add granular permissions and security control for accessing
|
||||
and utilizing certain resources in your experience, such as data stores and
|
||||
places.
|
||||
|
||||
All Open Cloud APIs require you to create an API key with valid permissions and
|
||||
include an `x-api-key` header in your request, which allows the application to
|
||||
authenticate to Open Cloud on your behalf.
|
||||
|
||||
## Create API keys
|
||||
|
||||
<Alert severity="warning">
|
||||
All references to API keys in the text below refer to user-owned keys.
|
||||
</Alert>
|
||||
|
||||
You can create and configure API keys to access your resources. An API key's access is determined by the permissions of the user who owns it. This means it can generally access any resource the user has permissions for, including their individual experiences and any [group-owned](../../projects/groups.md) experiences where they have the appropriate role. Some scopes can be restricted to specific experiences, but not all.
|
||||
|
||||
For details on how to create API keys for managing group resources, see the [Create API keys for managing group-owned resources](#create-api-keys-for-managing-group-owned-resources) section below.
|
||||
|
||||
To create an API key:
|
||||
|
||||
1. In the [Creator Dashboard](https://create.roblox.com/dashboard/creations), go to the [API Keys](https://create.roblox.com/dashboard/credentials?activeTab=ApiKeysTab) page.
|
||||
1. Click the **Create API Key** button.
|
||||
1. Enter a unique name for your API key. Use a name that can help you recall the
|
||||
purpose later, such as `PLACE_PUBLISHING_KEY` for publishing places to your
|
||||
experience.
|
||||
1. In the **Access Permissions** section, select an API from the **Select API
|
||||
System** menu. Repeat this step if
|
||||
you need to add multiple APIs to the key.
|
||||
|
||||
1. If applicable, select the experience that you want to access with the API key.
|
||||
|
||||
You can optionally disable **Restrict by Experience**. When disabled, your API key has access to all of your user-owned experiences and any group-owned experiences where you have the appropriate permissions, including any experiences you create in the future.
|
||||
|
||||
1. From the **Select Operations** dropdown, select the operations that you
|
||||
want to enable for the API key.
|
||||
|
||||
Most operations in the [API reference](../index.md) include the required permission scopes. For example, the [flush memory store](/cloud/reference/MemoryStore#Cloud_FlushMemoryStore) operation requires the `universe.memory-store:flush` permission.
|
||||
|
||||
For a list of all scopes and the APIs they support, see [Scopes](../reference/scopes.md).
|
||||
|
||||
1. **(Optional)** In the **Security** section, explicitly restrict IP access to the key using [CIDR
|
||||
notation](#cidr-format). You can find
|
||||
the IP address of your local machine and add it to the **Accepted IP
|
||||
Addresses** section along with additional IP addresses for those that need
|
||||
access. If you don't have a fixed IP, or you are using the API key only in a
|
||||
local environment, you can leave the `Restrict IP addresses` toggle unchecked to allow any IP to use your API key.
|
||||
|
||||
1. **(Optional)**: To add additional protection for your resources, set an expiration date for your key.
|
||||
1. Click the **Save & Generate key** button.
|
||||
1. Copy and save the API key string to a secure location, **not** a public repository for your code.
|
||||
1. Verify the status of your API key on the
|
||||
[API Extensions](https://create.roblox.com/dashboard/credentials) page of **Creator
|
||||
Dashboard**.
|
||||
|
||||
<Alert severity="warning">
|
||||
The API key string is equivalent to a password for your application. Never share it with untrusted parties, such as anyone outside of your development team.
|
||||
</Alert>
|
||||
|
||||
## Create API keys for managing group-owned resources
|
||||
|
||||
An API key grants access to all resources the user account has permissions for, including personal experiences outside of the group. If you use your personal account's API key for group automation and that key is compromised, other resources you have access to are also at risk.
|
||||
|
||||
To prevent this, we **strongly recommend** creating a separate API key on a dedicated alternate account with access strictly limited to the target group. This new account dedicated for automation purposes should only be given access to the target group and granted the minimal permissions required for its task.
|
||||
|
||||
1. Create a new, dedicated Roblox account for your automation.
|
||||
1. Invite the new account to your group.
|
||||
1. Assign it a group role with the minimum permissions required for its task (e.g., only "Create and edit group experiences").
|
||||
1. Log in to the new account and follow the steps in the section above to [create an API key](#create-api-keys).
|
||||
1. Use the generated API key for group resource automation.
|
||||
|
||||
## Best Practices For Managing API Keys
|
||||
|
||||
API keys are sensitive credentials that should be kept secure to prevent unauthorized access to your data. Here are some best practices for managing API keys.
|
||||
|
||||
- **Create separate keys for each application**: Create separate API keys for each application or use case to isolate access and reduce the impact if a key is compromised.
|
||||
|
||||
- **Select the minimum permissions needed**: When configuring scopes, select the minimum permissions necessary for the key's intended use. For those scopes that allow you to restrict scope access by experience, limit access to only the specific experiences that are needed.
|
||||
|
||||
- **Use IP address restrictions**: Restrict API key access to specific IP addresses or CIDR ranges to prevent unauthorized usage from unknown locations. Do not use IP address restrictions when using your API key in Roblox places to ensure your key can be used with Roblox servers.
|
||||
|
||||
- **Set expiration dates**: For short-term use cases, configure expiration dates to automatically disable keys after a set period, reducing the risk if a key is compromised. Setting expiration dates is not recommended for longer-term use cases unless you have a key rotation process in place, as your automation can unexpectedly fail when the key expires.
|
||||
|
||||
- **Use dedicated alternate accounts for group resource management**: Use a dedicated account with minimal permissions for group resource management, as detailed in the [Create API keys for managing group-owned resources](#create-api-keys-for-managing-group-owned-resources) section.
|
||||
|
||||
- **Store API keys securely**: Never store API keys directly in your source code, version control systems, or scripts where they could be exposed. Use a secrets management system for storing and controlling access to your keys. In Roblox places, use a [Secrets Store](cloud-services/secrets).
|
||||
|
||||
- **Do not share API keys through public channels**: Never share API keys through public communication channels, forums, or social media. Only share keys through secure, private channels with trusted team members. Limit access to who you share your keys with to minimize the blast radius if a key is compromised.
|
||||
|
||||
## CIDR format
|
||||
|
||||
To further protect your resources, when [creating an API
|
||||
key](#create-api-keys), specify IP addresses that can access the API key with
|
||||
either normal IP addresses or using the [CIDR
|
||||
notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation).
|
||||
A CIDR IP address looks like a normal IP address except it ends with a slash and
|
||||
a decimal that represents how many bits of the IP address are significant for
|
||||
network routing:
|
||||
|
||||
- **Normal**: 192.168.0.0
|
||||
- **CIDR**: 192.168.0.0/24
|
||||
|
||||
The former part is the IP address and the latter part is the **netmask**,
|
||||
counting the bits of 1s in binary format. In the previous example, **24** means
|
||||
**255.255.255.0** (24 1s) that allows all IPs between **192.168.0.0** and
|
||||
**192.168.0.255**. Understanding CIDR format is particularly useful if you plan
|
||||
to run your applications on a server.
|
||||
|
||||
## API key status
|
||||
|
||||
API keys initially have an active status, but they can become inactive over
|
||||
their lifetime. To learn why an API key has changed status and how to return the
|
||||
API key back to an active status, see the following table.
|
||||
|
||||
<Alert severity="warning"> If you or your group don't use or update an API key
|
||||
for 60 days, it automatically expires, even if it doesn't have a set expiration
|
||||
date. This reduces the risk of bad actors using old API keys. If you're no
|
||||
longer using an API key, you should manually disable or delete it. </Alert>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Status</th>
|
||||
<th>Reason</th>
|
||||
<th>Resolution</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Active</td>
|
||||
<td>No issues. The user can use the key to authenticate API calls.</td>
|
||||
<td>N/A</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Disabled</td>
|
||||
<td>The user disabled the key by disabling the <b>Enable Key</b> toggle.</td>
|
||||
<td>Enable the <b>Enable Key</b> toggle.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Expired</td>
|
||||
<td>The key's expiration date has passed.</td>
|
||||
<td>Either remove or set a new expiration date.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Auto-Expired</td>
|
||||
<td>The user hasn't used or updated the key in the past 60 days.</td>
|
||||
<td>You can either disable then enable the <b>Enable Key</b> toggle, or you can update any of the key's properties, such as the name, description, or expiration date.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Revoked</td>
|
||||
<td>For group keys only. The account that generated the key no longer has the sufficient access permission to manage the group's keys.</td>
|
||||
<td>Click the <b>Regenerate Key</b> to get a new secret.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Moderated</td>
|
||||
<td>A Roblox admin changed the key's secret for security reasons.</td>
|
||||
<td>Click the <b>Regenerate Key</b> to get a new secret.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>User Moderated</td>
|
||||
<td>The account that generated the key is under moderation by Roblox.</td>
|
||||
<td>Resolve the moderation issue on the account.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Introspect API keys
|
||||
|
||||
### `POST` api-keys/v1/introspect
|
||||
|
||||
Retrieve information about an API key. Verifies whether the key can be used from the requester's IP address and whether the key or the last generated user is moderated.
|
||||
|
||||
<h4>Request</h4>
|
||||
|
||||
`(application/json)`
|
||||
|
||||
| Key | Value |
|
||||
| -------------- | ---------------------- |
|
||||
| apiKey | `<api_key>` |
|
||||
|
||||
```bash title="Example Introspect API Key Request"
|
||||
curl --location --request POST 'https://apis.roblox.com/api-keys/v1/introspect' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"apiKey": "your-api-key"
|
||||
}'
|
||||
```
|
||||
|
||||
<h4>Response</h4>
|
||||
|
||||
There are four possible resource identifiers that can be present in each scope object:
|
||||
|
||||
- userId
|
||||
- groupId
|
||||
- universeId
|
||||
- universeDatastore
|
||||
|
||||
The userId and groupId identifiers are only relevant to scopes with the creator target. The universeDatastore identifier is only relevant to scopes with the universe-datastore target. The resource identifier will be omitted for scopes that do not support resource selection.
|
||||
|
||||
An asterisk (`*`) in the resource identifier list indicates that the scope has permission on all resources of that type.
|
||||
|
||||
```json title="Example Introspect API Key Response"
|
||||
{
|
||||
"name": "test key",
|
||||
"authorizedUserId": 234,
|
||||
"scopes": [
|
||||
{
|
||||
"name": "universe-datastores.objects",
|
||||
"operations": [
|
||||
"create"
|
||||
],
|
||||
"universeDatastores": [
|
||||
{
|
||||
"universeId": "123",
|
||||
"datastoreName": "playerData"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "asset",
|
||||
"operations": [
|
||||
"write"
|
||||
],
|
||||
"groupIds": [
|
||||
"*"
|
||||
],
|
||||
"userIds": [
|
||||
"*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"enabled": true,
|
||||
"expired": false,
|
||||
"expirationTimeUtc": "2026-01-01T12:00:00.000Z"
|
||||
}
|
||||
```
|
||||
206
.cursor/rules/roblox/en-us/cloud/auth/oauth2-develop.md
Normal file
206
.cursor/rules/roblox/en-us/cloud/auth/oauth2-develop.md
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
---
|
||||
title: OAuth 2.0 app implementation
|
||||
description: Introduces OAuth 2.0 authentication implementation.
|
||||
---
|
||||
|
||||
Open Cloud supports the OAuth 2.0 authorization flow with and without
|
||||
[PKCE](../../cloud/auth/oauth2-overview.md#authorization-code-flow-with-pkce),
|
||||
depending on whether your clients are confidential or public.
|
||||
|
||||
- _Confidential clients_ are apps that are capable of keeping credentials
|
||||
confidential, such as a website that can securely store and retrieve secrets on
|
||||
its backend.
|
||||
- _Public clients_ are apps that can't keep secrets, such as mobile
|
||||
and web browser apps.
|
||||
|
||||
We recommend the OAuth 2.0 authorization code flow with PKCE for _all_ clients
|
||||
and require it for public clients.
|
||||
|
||||
<Alert severity="warning">
|
||||
Store the client secret in a secure place and never expose it to the public. Bad
|
||||
actors can use it to impersonate your application.
|
||||
</Alert>
|
||||
|
||||
To implement the authorization code flow, your app performs the following steps:
|
||||
|
||||
1. Generate a code verifier and code challenge (PKCE only). This lets you
|
||||
include a challenge in your requests rather than the client secret, which
|
||||
improves security.
|
||||
1. Send a `GET` request to the authorization endpoint with the appropriate parameters.
|
||||
1. Handle the authorization callback. After obtaining authorization, use the
|
||||
authorization code from Roblox in a redirect request to the URL you specified
|
||||
during app creation. Parse the authorization code for later use.
|
||||
1. Send a `POST` request to the token endpoint with the authorization code. If
|
||||
successful, you receive access and refresh tokens with which to make API
|
||||
calls.
|
||||
1. Call any Open Cloud API that supports OAuth 2.0 authentication based on the
|
||||
reference documentation for the resources you want to access.
|
||||
|
||||
The following sections describe each step in greater depth.
|
||||
|
||||
## Generate a code challenge (for PKCE only)
|
||||
|
||||
Before initiating the authorization process, you need to generate a code
|
||||
challenge from a code verifier. You can use libraries or built-in functions in
|
||||
the programming language of your choice to create the code verifier, calculate
|
||||
the hash, and perform Base64 encoding to generate the code challenge.
|
||||
|
||||
When creating the code verifier, only use unreserved characters, including
|
||||
uppercase and lowercase letters (A-Z, a-z), decimal digits (0-9), hyphen (-),
|
||||
period (.), underscore (\_), and tilde (~), with a minimum length of 43
|
||||
characters and a maximum length of 128 characters.
|
||||
|
||||
The following example shows how to use Javascript to create a code verifier and
|
||||
generate the code challenge using the SHA-256 hashing algorithm:
|
||||
|
||||
```javascript title="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));
|
||||
```
|
||||
|
||||
For PKCE, you need both the code verifier and challenge values in later steps.
|
||||
|
||||
## Construct the authorization URL
|
||||
|
||||
<Alert severity="info">
|
||||
See the [authorization endpoint reference documentation](oauth2-reference.md#get-v1authorize)
|
||||
for complete information on how to construct the authorization URL.
|
||||
</Alert>
|
||||
|
||||
To initiate the user authorization process, construct an
|
||||
authorization URL with the required parameters:
|
||||
|
||||
- `client_id`: Your app's client ID obtained after [registering your app](oauth2-registration.md).
|
||||
- `redirect_uri`: Your app's redirect URI, the re-entry point of your app.
|
||||
- `scope`: The requested scopes that define the access permissions your app
|
||||
needs in a space-separated list.
|
||||
- `response_type`: Set it to `code` to indicate the authorization code flow.
|
||||
|
||||
**Required for PKCE only**
|
||||
|
||||
- `code_challenge`: The code challenge generated from a code verifier.
|
||||
- `code_challenge_method`: Set this parameter value to `S256` to indicate that
|
||||
the code challenge was transformed using the SHA-256 algorithm, the most
|
||||
widely supported and secure code challenge method.
|
||||
- `state`: An opaque, secure random value to maintain state
|
||||
between the request and callback.
|
||||
|
||||
**Required for non-PKCE only**
|
||||
|
||||
- `client_secret`: Your app's client secret obtained after [registering your app](oauth2-registration.md). If you are using authentication with
|
||||
PKCE, omit this parameter.
|
||||
Your authorization request URL must be well formatted, like in the following
|
||||
example:
|
||||
|
||||
```bash title="Example PKCE Authorization 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
|
||||
```
|
||||
|
||||
When users visit the URL, they are taken through the authorization flow. If
|
||||
successful, Roblox redirects the user to the specified `redirect_uri`.
|
||||
|
||||
## Handle authorization callbacks
|
||||
|
||||
When an authorization flow is successful, your app receives a `GET` request from
|
||||
the Roblox authorization server at the `redirect_uri` that you specified. In the
|
||||
request, you receive `code` (authorization code) and `state`(if you provided a
|
||||
value previously) parameters.
|
||||
|
||||
- The `code` parameter contains an authorization code that the app can
|
||||
exchange for an access token from the authorization server. Most backend
|
||||
server languages have standard ways to access query parameters as decoded
|
||||
objects. You'll need to obtain the `code` parameter and use it to exchange
|
||||
for access tokens.
|
||||
|
||||
- The `state` parameter is an opaque value that you initially provided in the
|
||||
authorization request. You can use this parameter to maintain the state or
|
||||
context of the authorization process.
|
||||
|
||||
For example, you might receive a `GET` request with the following URL if you
|
||||
specified your redirect URI to be `https://example.com/redirect`.
|
||||
|
||||
```bash title="Example Redirect URL"
|
||||
https://example.com/redirect?code=10c45PNuquKnFJ6pUcy5-fHkghEM6lSegm-7hj9mVEprub1dSDuStuKK_EAUXY7AHTD63xcnmvxSLthp-C8g3jzIGZVzuXSd20Y2dEYI9hx0LZmPg95ME4z2K03UheiZbroyXUjYyB3ReoMqobzDVPzyx6IS8kj2Uu-11Xq_0JiTYxtDatuqXRNIAmJT8gMJmbSyOLOP_vnDvbeMUiBsqCRrkTGVbWSwYSc8sTVVE-535kYdqQOgNjH1ffCoZLGl8YYxLnpb2CXJlRQPrcjkA&state=6789
|
||||
```
|
||||
|
||||
If authorization fails, your app receives a `GET` request to the specified
|
||||
redirect URL with the `error`, `error_description`, and `state` (if applicable)
|
||||
parameters.
|
||||
|
||||
- The `error` parameter indicates the specific OAuth 2.0 error that occurred
|
||||
during the authorization process.
|
||||
- The `error_description` parameter provides additional details of the error.
|
||||
- The `state` parameter helps your app maintain state in the case of a
|
||||
failure.
|
||||
|
||||
## Exchange an authorization code for access tokens
|
||||
|
||||
When you have parsed the authorization `code`, exchange it for
|
||||
tokens to access desired Roblox resources:
|
||||
|
||||
1. Request an access token and refresh token by sending a `POST` request to the
|
||||
[token exchange endpoint](oauth2-reference.md#post-v1token). The
|
||||
request must include the authorization code, client ID, and the code
|
||||
verifier value (PKCE) or client secret (non-PKCE) in `x-www-form-urlencoded` format.
|
||||
|
||||
1. Parse the applicable tokens from the response received. The access token is
|
||||
valid for 15 minutes. Store the refresh token securely, typically on the server side, so you can use it to obtain new tokens in the future.
|
||||
|
||||
```json title="Example Token Endpoint Response"
|
||||
{
|
||||
"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"
|
||||
}
|
||||
```
|
||||
|
||||
## Make a call to a resource method
|
||||
|
||||
Now that you have the required access token, you can use it to make
|
||||
authenticated calls to resource methods. Include the access token in the header of all API requests to
|
||||
authorize them.
|
||||
|
||||
For example, you can test if your app functions correctly by
|
||||
going through the entire authorization flow and then making a `GET` request
|
||||
to the
|
||||
[user information endpoint](oauth2-reference.md#get-v1userinfo) with an access
|
||||
token. Ensure you have the `openid` or both the `openid` and `profile`
|
||||
scopes before calling this endpoint. If successful, the response from that
|
||||
endpoint looks like this:
|
||||
|
||||
```json title="Example User Information Response"
|
||||
{
|
||||
"sub": "12345678",
|
||||
"name": "Jane Doe",
|
||||
"nickname": "robloxjanedoe",
|
||||
"preferred_username": "robloxjanedoe",
|
||||
"created_at": 1607354232,
|
||||
"profile": "https://www.roblox.com/users/12345678/profile"
|
||||
}
|
||||
```
|
||||
167
.cursor/rules/roblox/en-us/cloud/auth/oauth2-overview.md
Normal file
167
.cursor/rules/roblox/en-us/cloud/auth/oauth2-overview.md
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
---
|
||||
title: OAuth 2.0 overview
|
||||
description: Introduces the 3rd-party app creation support with OAuth 2.0 authorization framework.
|
||||
---
|
||||
|
||||
You can build or authorize apps that use Open Cloud APIs to access Roblox
|
||||
resources. Open Cloud provides authentication for these apps using OAuth 2.0.
|
||||
|
||||
<dl>
|
||||
|
||||
<dt>**As an experience creator or group owner**</dt>
|
||||
<dd>
|
||||
You can securely use tools created by others to improve your creation
|
||||
productivity. The OAuth 2.0 authorization layer allows you to grant permissions
|
||||
to third-party apps to access your or your group's experiences without giving
|
||||
them your credentials and personal information. You select the access
|
||||
permissions of your specific Roblox resources, and Roblox handles the
|
||||
authorization process for you with the OAuth 2.0 framework.
|
||||
<Alert severity="info">
|
||||
You must have a 13+ account to authorize OAuth 2.0 apps.
|
||||
</Alert>
|
||||
</dd>
|
||||
|
||||
<dt>**As an app developer**</dt>
|
||||
<dd>
|
||||
You can create apps for yourself and others in the Roblox community. OAuth 2.0
|
||||
defines the roles involved in the authorization process, the protocol of how
|
||||
roles interact with each other, and the authorization flows that you need to
|
||||
follow to develop secure and compatible apps.
|
||||
<Alert severity="info">
|
||||
You must be [ID verified](../../production/publishing/account-verification.md#verify-through-government-id)
|
||||
to register and publish OAuth 2.0 apps.
|
||||
</Alert>
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
## Roles
|
||||
|
||||
The Open Cloud OAuth 2.0 protocol has the following roles. It's useful to
|
||||
understand the specific roles before learning about how they interact with one
|
||||
another in authorization flows.
|
||||
|
||||
- **Resource owner**: An entity capable of granting access to a protected
|
||||
resource. For example, a creator who allows a third-party app to access
|
||||
their Roblox resources through Open Cloud Web APIs.
|
||||
|
||||
- **Resource server**: A Roblox service that hosts protected resources and
|
||||
responds to requests from a resource owner.
|
||||
|
||||
- **Client**: An app that accesses protected resources on behalf of the resource
|
||||
owner (with the owner's authorization).
|
||||
|
||||
- **Authorization server**: The Roblox server that authenticates the identity of
|
||||
the resource owner and issues access tokens to the client.
|
||||
|
||||
## Grant types
|
||||
|
||||
Authorization flows, or grant types, are the steps of actions that roles perform
|
||||
during the authorization process. Roblox supports the OAuth 2.0 authorization
|
||||
code flow and its Proof Key for Code Exchange (PKCE) extension, with different
|
||||
implementation requirements for apps that are capable or incapable of storing
|
||||
client secrets.
|
||||
|
||||
### Authorization code flow
|
||||
|
||||
Through the authorization code flow, a client exchanges an authorization code
|
||||
for an access token and a refresh token to complete the authorization process in
|
||||
the following steps:
|
||||
|
||||
1. The client sends an authorization request to the Roblox authorization server.
|
||||
|
||||
1. The authorization server verifies the identity of the resource owner.
|
||||
|
||||
1. The authorization server receives permissions for accessing specific Roblox
|
||||
resources from the resource owner.
|
||||
|
||||
1. The authorization server redirects the resource owner back to the client with
|
||||
an authorization code.
|
||||
|
||||
1. The client requests an access token using the authorization code at the token
|
||||
endpoint.
|
||||
|
||||
1. The client receives a response from the token endpoint containing an access
|
||||
token, an ID token, and a refresh token.
|
||||
|
||||
1. The client retrieves the permitted resources after getting the access token.
|
||||
|
||||
The following figure describes the interactions between roles in the
|
||||
authorization code flow that you'll read in the following sections:
|
||||
|
||||
<img src="../../assets/open-cloud/protocol-flow.png" width="80%" />
|
||||
|
||||
### Authorization code flow with PKCE
|
||||
|
||||
The [PKCE extension](https://www.rfc-editor.org/rfc/rfc7636) of the
|
||||
authorization code flow helps reduce risk of leaking the authorization code and
|
||||
prevent cross-site request forgery (CSRF), an attack that tricks users into
|
||||
submitting unintended web requests. This flow completes the authorization
|
||||
process with the following steps:
|
||||
|
||||
1. The client generates a unique and cryptographically random key called a
|
||||
_code verifier_ for every authorization request.
|
||||
|
||||
1. The client runs a SHA-256 hash algorithm on the code verifier to generate a
|
||||
_code challenge_.
|
||||
|
||||
1. If the client:
|
||||
|
||||
- Is a [public client](oauth2-develop.md#public-clients),
|
||||
instead of using the client secret, it passes the client ID and the code
|
||||
challenge in the authorization request.
|
||||
|
||||
- Is a [confidential client](oauth2-develop.md#confidential-clients),
|
||||
it adds the code challenge along with the client ID and secret in the
|
||||
request.
|
||||
|
||||
1. The client sends an authorization request to the Roblox authorization server.
|
||||
|
||||
1. The authorization server verifies the identity of the resource owner.
|
||||
|
||||
1. The authorization server receives permissions for accessing specific Roblox
|
||||
resources from the resource owner.
|
||||
|
||||
1. The authorization server redirects the resource owner back to the client with
|
||||
an authorization code.
|
||||
|
||||
1. The client includes the authorization code and the original code verifier
|
||||
in the token request to the [token endpoint](oauth2-reference.md#token-exchange).
|
||||
|
||||
1. The authorization server verifies the authorization code and the associated
|
||||
code verifier.
|
||||
|
||||
1. The client receives a response from the token endpoint containing an access
|
||||
token, an ID token, and a refresh token.
|
||||
|
||||
1. The client retrieves the permitted resources after getting the access token.
|
||||
|
||||
## OpenID Connect support
|
||||
|
||||
Roblox uses [OpenID Connect (OIDC)](https://openid.net/connect/) as an
|
||||
identity layer on top of the OAuth 2.0 protocol for authentication to protect
|
||||
sensitive account information. OIDC allows applications to verify the identity
|
||||
of users and obtain their basic public profile information, such as user ID,
|
||||
usernames, display names, and profile links.
|
||||
|
||||
<Alert severity="info">
|
||||
When [adding permission scopes](oauth2-registration.md#register-an-app) to your app on
|
||||
**Creator Dashboard**, make sure to select the `openid` identity scope for
|
||||
receiving an ID token in the token response as part of the authentication
|
||||
process.
|
||||
</Alert>
|
||||
|
||||
## Registration and implementation
|
||||
|
||||
To implement a web or mobile app that uses authorization code flow, you need to:
|
||||
|
||||
1. [Register](oauth2-registration.md) your app with Roblox.
|
||||
This lets you obtain a client ID and secret to register your app with Roblox
|
||||
and make calls to your endpoints.
|
||||
|
||||
1. [Implement](oauth2-develop.md) the authorization code
|
||||
flow. For a complete reference of the OAuth 2.0 endpoints that you need to
|
||||
call, see the [Authentication](oauth2-reference.md) reference.
|
||||
|
||||
1. Go through the [review process](oauth2-registration.md#submit-for-review)
|
||||
to get more user quota.
|
||||
427
.cursor/rules/roblox/en-us/cloud/auth/oauth2-reference.md
Normal file
427
.cursor/rules/roblox/en-us/cloud/auth/oauth2-reference.md
Normal file
|
|
@ -0,0 +1,427 @@
|
|||
---
|
||||
title: OAuth 2.0 authentication
|
||||
description: Describes how to make authenticated calls to Open Cloud with API keys and OAuth 2.0
|
||||
---
|
||||
|
||||
<Alert severity="warning">
|
||||
OAuth 2.0 authentication is a beta feature that might be subject to change for
|
||||
future releases. All Open Cloud endpoints also support
|
||||
[API key authentication](../auth/api-keys.md).
|
||||
</Alert>
|
||||
|
||||
<Alert severity="info">
|
||||
For complete implementation guides and information on OAuth 2.0, including a
|
||||
sample app, see the [OAuth 2.0 overview](../auth/oauth2-overview.md).
|
||||
</Alert>
|
||||
|
||||
This document describes endpoints that you call to implement the OAuth 2.0
|
||||
authorization code flow, as well as other endpoints useful for implementing
|
||||
authentication in your apps.
|
||||
|
||||
```http title="Base URL"
|
||||
https://apis.roblox.com/oauth
|
||||
```
|
||||
|
||||
```http title="Endpoints"
|
||||
GET v1/authorize
|
||||
POST v1/token
|
||||
POST v1/token/introspect
|
||||
POST v1/token/resources
|
||||
POST v1/token/revoke
|
||||
GET v1/userinfo
|
||||
GET .well-known/openid-configuration
|
||||
```
|
||||
|
||||
## Authorization
|
||||
|
||||
### `GET` v1/authorize
|
||||
|
||||
Obtains authorization from the user to authenticate with their Roblox account.
|
||||
Expects a valid authorization URL constructed with
|
||||
the specified parameters. This endpoint supports PKCE authorization.
|
||||
|
||||
<h4>Query parameters</h4>
|
||||
|
||||
| Name | Description | Required | Example |
|
||||
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------- |
|
||||
| client_id | The app's client ID. | yes | `816547628409595165403873012` |
|
||||
| redirect_uri | The URL that users are redirected back to after the completing authorization flow. | yes | `https://www.roblox.com/example-redirect` |
|
||||
| scope | The requested scopes, space delimited. Use the `openid` scope to receive an ID token. Use the `openid` and `profile` scope to obtain more user information. | yes | `openid profile` |
|
||||
| response_type | The credentials the app wants returned. The default is the authorization code grant type. | yes | `none`, `code` |
|
||||
| prompt | Specifies what authentication and consent pages are shown to users. Certain screens are required for third-party apps and can't be skipped. | no | `none`, `login`, `consent`, `select_account` |
|
||||
| nonce | The cryptographic number that binds the token with the client. | no | `<random_value_1>` |
|
||||
| state | An opaque value that prevents cross-site request forgery, a type of malicious attack. Passed back to the app after authorization. | no | `<app-provided-opaque-value>` |
|
||||
| code_challenge | The resulting string of applying the `code_challenge_method` to the `code_verifier`. | no | Base64-URL-encoded string |
|
||||
| code_challenge_method | The function that is applied to the `code_verifier`. | no | S256 |
|
||||
|
||||
<h4>Request</h4>
|
||||
|
||||
```plain title="Example Request of Directing to Authorization Flow"
|
||||
https://apis.roblox.com/oauth/v1/authorize?client_id=816547628409595165403873012&redirect_uri=https://my-app.com/redirect&scope=openid&response_type=code&nonce=12345&state=6789
|
||||
```
|
||||
|
||||
<h4>Response</h4>
|
||||
|
||||
After calling this endpoint, the user is redirected to the specified redirect
|
||||
URL with the authorization code in a `code` query parameter.
|
||||
The authorization code:
|
||||
|
||||
- Has a lifetime of one minute.
|
||||
- Can only be redeemed once.
|
||||
- Is invalid after one use.
|
||||
|
||||
## Token exchange
|
||||
|
||||
To obtain tokens to access APIs, exchange an **authorization code** for a set of
|
||||
confidential tokens. All token endpoints support two types of client
|
||||
authentication:
|
||||
|
||||
1. HTTP Basic Authentication Scheme with an authorization header:
|
||||
`Authorization: Basic Base64 encoded(<client_id>:<client_secret>)`.
|
||||
1. Client ID and secret in the request body as parameters.
|
||||
|
||||
The following list describes the various tokens you receive from this
|
||||
endpoint.
|
||||
|
||||
- **Access token** - Represents the authorization from a creator or user for a
|
||||
third-party app to access their protected Roblox resources. It's a string
|
||||
denoting a specific scope, lifetime, and other access attributes. Once the
|
||||
Roblox authorization server issues an access token to an app, the token:
|
||||
|
||||
- Is valid for 15 minutes.
|
||||
- Can be used multiple times before it expires.
|
||||
- Can be invalidated before it expires if an app user revokes the authorization.
|
||||
|
||||
- **Refresh token** - Refreshes an authorization session. An app can use
|
||||
the refresh token to obtain a new set of tokens, which includes an access token,
|
||||
a refresh token, and an ID token. A refresh token:
|
||||
|
||||
- Is valid for 90 days.
|
||||
- Can only be used once before it expires to refresh tokens.
|
||||
- Can be invalidated before it expires if an app user revokes the authorization.
|
||||
|
||||
- **ID token** - Provides proof that a user's identity has been authenticated. Its
|
||||
content depends on the scopes requested and can contain basic user information,
|
||||
including a user's Roblox display name and username. The ID token is only for
|
||||
identity authentication purposes and doesn't provide access to any Roblox
|
||||
resources.
|
||||
|
||||
### `POST` v1/token
|
||||
|
||||
Obtain a set of tokens with an authorization code.
|
||||
|
||||
<h4>Request</h4>
|
||||
|
||||
`(x-www-form-urlencoded)`
|
||||
|
||||
| Key | Value |
|
||||
| ------------- | ---------------------------- |
|
||||
| code | `<authorization code>` |
|
||||
| code_verifier | `<pkce code verifier value>` |
|
||||
| grant_type | authorization_code |
|
||||
| client_id | `<client_id>` |
|
||||
| client_secret | `<client_secret>` |
|
||||
|
||||
```bash title="Example Obtain Token Request"
|
||||
curl --location --request POST 'https://apis.roblox.com/oauth/v1/token' \
|
||||
--header 'Content-Type: application/x-www-form-urlencoded' \
|
||||
--data-urlencode 'client_id=840974200211308101' \
|
||||
--data-urlencode 'client_secret=RBX-CR9...St12L' \
|
||||
--data-urlencode 'grant_type=authorization_code' \
|
||||
--data-urlencode 'code=yCnq4ofX1...XmGpdx'
|
||||
```
|
||||
|
||||
<h4>Response</h4>
|
||||
|
||||
```json title="Example Obtain Token Response"
|
||||
{
|
||||
"access_token": "...",
|
||||
"refresh_token": "...",
|
||||
"token_type": "Bearer",
|
||||
"expires_in": 899,
|
||||
"scope": "universe-messaging-service:publish"
|
||||
}
|
||||
```
|
||||
|
||||
### `POST` v1/token
|
||||
|
||||
Obtain a set of tokens with a refresh token.
|
||||
|
||||
<h4>Request</h4>
|
||||
|
||||
`(x-www-form-urlencoded)`
|
||||
|
||||
| Key | Value |
|
||||
| ------------- | ----------------- |
|
||||
| grant_type | refresh_token |
|
||||
| refresh_token | `<refresh_token>` |
|
||||
| client_id | `<client_id>` |
|
||||
| client_secret | `<client_secret>` |
|
||||
|
||||
```bash title="Example Refresh Token Request"
|
||||
curl --location --request POST 'https://apis.roblox.com/oauth/v1/token' \
|
||||
--header 'Content-Type: application/x-www-form-urlencoded' \
|
||||
--data-urlencode 'grant_type=refresh_token' \
|
||||
--data-urlencode 'refresh_token=Ujfstayclfdlbm...BGydlsnU' \
|
||||
--data-urlencode 'client_id=840974200211308101' \
|
||||
--data-urlencode 'client_secret=RBX-CR9...St12L'
|
||||
```
|
||||
|
||||
<h4>Response</h4>
|
||||
|
||||
```json title="Example Refresh Token Request"
|
||||
{
|
||||
"access_token": "...",
|
||||
"refresh_token": "...",
|
||||
"token_type": "Bearer",
|
||||
"expires_in": 899,
|
||||
"scope": "universe-messaging-service:publish"
|
||||
}
|
||||
```
|
||||
|
||||
### `POST` v1/token/introspect
|
||||
|
||||
Receive information about a token. Verifies whether the token is presently valid
|
||||
and hasn't expired yet. Useful for stateless validation. Use only if the API
|
||||
you're accessing doesn't require a resource, such as Assets API, or if you just
|
||||
want to see specific claims of the token.
|
||||
|
||||
<Alert severity="info"> Even if the user has revoked the authorization linked to
|
||||
the access token, the endpoint still shows the access token as `valid: true`
|
||||
because it checks whether the token is active based on its lifetime (typically
|
||||
15 minutes for access tokens). </Alert>
|
||||
|
||||
<h4>Request</h4>
|
||||
|
||||
`(x-www-form-urlencoded)`
|
||||
|
||||
| Key | Value |
|
||||
| ------------- | --------------------------------------------------- |
|
||||
| token | `<access_token>`, `<refresh_token>` or `<id_token>` |
|
||||
| client_id | `<client_id>` |
|
||||
| client_secret | `<client_secret>` |
|
||||
|
||||
```bash title="Example Introspect Token Request"
|
||||
curl --location --request POST 'https://apis.roblox.com/oauth/v1/token/introspect' \
|
||||
--header 'Content-Type: application/x-www-form-urlencoded' \
|
||||
--data-urlencode 'token=eyjlflabtfl...4gxqYBG' \
|
||||
--data-urlencode 'client_id=840974200211308101' \
|
||||
--data-urlencode 'client_secret=RBX-CR9...St12L'
|
||||
```
|
||||
|
||||
<h4>Response</h4>
|
||||
|
||||
```json title="Example Introspect Token Response"
|
||||
{
|
||||
"active": true,
|
||||
"jti": "RT.2GcjvTduKzk6QY9tjTfm",
|
||||
"iss": "https://apis.roblox.com/oauth/",
|
||||
"token_type": "Bearer",
|
||||
"client_id": "840974200211308101",
|
||||
"aud": "4239311013248676173",
|
||||
"sub": "1516563360",
|
||||
"scope": "universe-messaging-service:publish",
|
||||
"exp": 1676394509,
|
||||
"iat": 1660842510
|
||||
}
|
||||
```
|
||||
|
||||
### `POST` v1/token/resources
|
||||
|
||||
Check whether a token can access a specific resource by obtaining the list of
|
||||
user resources that the user gave permission for. This is useful for stateful
|
||||
validation.
|
||||
|
||||
<h4>Request</h4>
|
||||
|
||||
`(x-www-form-urlencoded)`
|
||||
|
||||
| Key | Value |
|
||||
| ------------- | ----------------- |
|
||||
| token | `<access_token>` |
|
||||
| client_id | `<client_id>` |
|
||||
| client_secret | `<client_secret>` |
|
||||
|
||||
```bash title="Example Obtain Token Resources Request"
|
||||
curl --location --request POST https://apis.roblox.com/oauth/v1/token/resources' \
|
||||
--header 'Content-Type: application/x-www-form-urlencoded' \
|
||||
--data-urlencode 'token=eyjlflabtfl...4gxqYBG' \
|
||||
--data-urlencode 'client_id=840974200211308101' \
|
||||
--data-urlencode 'client_secret=RBX-CR9...St12L'
|
||||
```
|
||||
|
||||
<h4>Response</h4>
|
||||
|
||||
The value `U` in `ids` indicates that a scope has granted access to a resource owned by the authorizing `owner`.
|
||||
|
||||
```json title="Example Obtain Token Resources Response"
|
||||
{
|
||||
"resource_infos": [
|
||||
{
|
||||
"owner": {
|
||||
"id": "1516563360",
|
||||
"type": "User"
|
||||
},
|
||||
"resources": {
|
||||
"universe": {
|
||||
"ids": ["3828411582"]
|
||||
},
|
||||
"creator": {
|
||||
"ids": ["U"]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### `POST` v1/token/revoke
|
||||
|
||||
Revoke an authorization session using the provided refresh token.
|
||||
|
||||
<h4>Request</h4>
|
||||
|
||||
`(x-www-form-urlencoded)`
|
||||
|
||||
| Key | Value |
|
||||
| ------------- | ----------------- |
|
||||
| token | `<refresh_token>` |
|
||||
| client_id | `<client_id>` |
|
||||
| client_secret | `<client_secret>` |
|
||||
|
||||
```bash title="Example Revoke Token Request"
|
||||
curl --location --request POST https://apis.roblox.com/oauth/v1/token/revoke' \
|
||||
--header 'Content-Type: application/x-www-form-urlencoded' \
|
||||
--data-urlencode 'token=Ujfstayclfdlbm...BGydlsnU' \
|
||||
--data-urlencode 'client_id=840974200211308101' \
|
||||
--data-urlencode 'client_secret=RBX-CR9...St12L'
|
||||
```
|
||||
|
||||
<h4>Response</h4>
|
||||
|
||||
`200 OK` with an empty response
|
||||
|
||||
## User Information
|
||||
|
||||
### `GET` /v1/userinfo
|
||||
|
||||
Gets the Roblox user ID and other user metadata.
|
||||
|
||||
<h4>Request</h4>
|
||||
|
||||
**Authorization header**: `Authorization: Bearer <access_token>`
|
||||
|
||||
```bash title="Example Get User Info Request"
|
||||
curl --location --request GET 'https://apis.roblox.com/oauth/v1/userinfo' \
|
||||
--header 'Authorization: Bearer eyjlflabtfl...4gxqYBG'
|
||||
```
|
||||
|
||||
<h4>Response</h4>
|
||||
|
||||
You can use the `sub` value to uniquely identify the user. Users can change
|
||||
their Roblox username and display name, so don't use them as unique identifiers to refer to users on your app.
|
||||
|
||||
| Claim | Description |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| sub | Roblox user ID. |
|
||||
| name | Roblox display name. |
|
||||
| nickname | Roblox display name. |
|
||||
| preferred_username | Roblox username. |
|
||||
| created_at | Creation time of the Roblox account as a Unix timestamp. |
|
||||
| profile | Roblox account profile URL. |
|
||||
| picture | Roblox avatar headshot image. Can be null if the avatar headshot image hasn't yet been generated or has been moderated. |
|
||||
|
||||
```json title="Example User with Profile Scope"
|
||||
{
|
||||
"sub": "1516563360",
|
||||
"name": "exampleuser",
|
||||
"nickname": "exampleuser",
|
||||
"preferred_username": "exampleuser",
|
||||
"created_at": 1584682495,
|
||||
"profile": "https://www.roblox.com/users/1516563360/profile",
|
||||
"picture": "https://tr.rbxcdn.com/03dc2a9abe7b1aacaaf93ea46d5c0646/150/150/AvatarHeadshot/Png"
|
||||
}
|
||||
```
|
||||
|
||||
```json title="Example User without Profile Scope"
|
||||
{
|
||||
"sub": "1516563360"
|
||||
}
|
||||
```
|
||||
|
||||
## Discovery
|
||||
|
||||
The OpenID Connect (OIDC) Discovery Document is a JSON document that
|
||||
contains metadata about the Open Cloud configuration details, including a list
|
||||
of identity-related scopes and claims that are supported. You can use it to
|
||||
dynamically discover information about Open Cloud OAuth 2.0 endpoints and
|
||||
configuration, such as the authorization endpoint, token endpoint, and public
|
||||
key set.
|
||||
|
||||
After retrieving and fetching the Discovery Document from the Discovery document
|
||||
URI, you can either manually inspect fields in the response to verify the
|
||||
information, or you can create your own custom library mapping to fields in the
|
||||
response schema to automate your workflow.
|
||||
|
||||
### `GET` .well-known/openid-configuration
|
||||
|
||||
<h4>Response</h4>
|
||||
|
||||
All Discovery Document responses follow the same schema as the following example response.
|
||||
|
||||
<Alert severity="warning">
|
||||
Not all of the following scopes and claims are available to third-party app creators, as some can only be used by official Roblox apps.
|
||||
</Alert>
|
||||
|
||||
```json title="Example Discovery Document Response"
|
||||
{
|
||||
"issuer": "https://apis.roblox.com/oauth/",
|
||||
"authorization_endpoint": "https://apis.roblox.com/oauth/v1/authorize",
|
||||
"token_endpoint": "https://apis.roblox.com/oauth/v1/token",
|
||||
"introspection_endpoint": "https://apis.roblox.com/oauth/v1/token/introspect",
|
||||
"revocation_endpoint": "https://apis.roblox.com/oauth/v1/token/revoke",
|
||||
"resources_endpoint": "https://apis.roblox.com/oauth/v1/token/resources",
|
||||
"userinfo_endpoint": "https://apis.roblox.com/oauth/v1/userinfo",
|
||||
"jwks_uri": "https://apis.roblox.com/oauth/v1/certs",
|
||||
"registration_endpoint": "https://create.roblox.com/dashboard/credentials",
|
||||
"service_documentation": "https://create.roblox.com/docs/reference/cloud",
|
||||
"scopes_supported": [
|
||||
"openid",
|
||||
"profile",
|
||||
"email",
|
||||
"verification",
|
||||
"credentials",
|
||||
"age",
|
||||
"premium",
|
||||
"roles"
|
||||
],
|
||||
"response_types_supported": ["none", "code"],
|
||||
"subject_types_supported": ["public"],
|
||||
"id_token_signing_alg_values_supported": ["ES256"],
|
||||
"claims_supported": [
|
||||
"sub",
|
||||
"type",
|
||||
"iss",
|
||||
"aud",
|
||||
"exp",
|
||||
"iat",
|
||||
"nonce",
|
||||
"name",
|
||||
"nickname",
|
||||
"preferred_username",
|
||||
"created_at",
|
||||
"profile",
|
||||
"email",
|
||||
"email_verified",
|
||||
"verified",
|
||||
"age_bracket",
|
||||
"premium",
|
||||
"roles",
|
||||
"internal_user"
|
||||
],
|
||||
"token_endpoint_auth_methods_supported": [
|
||||
"client_secret_post",
|
||||
"client_secret_basic"
|
||||
]
|
||||
}
|
||||
```
|
||||
144
.cursor/rules/roblox/en-us/cloud/auth/oauth2-registration.md
Normal file
144
.cursor/rules/roblox/en-us/cloud/auth/oauth2-registration.md
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
---
|
||||
title: OAuth 2.0 app registration
|
||||
description: Explains how to register an app and how the review workflow works.
|
||||
---
|
||||
|
||||
Registering your OAuth 2.0 app allows it to access Roblox resources. After
|
||||
registration, Roblox assigns the app a unique client ID and secret that you can
|
||||
use to obtain authorization from users to access their Roblox information and
|
||||
resources.
|
||||
|
||||
<Alert severity="info">
|
||||
You can only register apps for individual accounts or groups that you own.
|
||||
</Alert>
|
||||
|
||||
## Register your app
|
||||
|
||||
To register an app:
|
||||
|
||||
1. In the [Creator Dashboard](https://create.roblox.com/dashboard/creations), go to the [OAuth 2.0 Apps](https://create.roblox.com/dashboard/credentials?activeTab=OAuthTab) page.
|
||||
1. Click the **Create App** button.
|
||||
1. Enter a valid and globally unique **Application Name**.
|
||||
1. Read and agree to the **Roblox Terms of Service** and click **Create**.
|
||||
1. Copy and store the **Client ID** and **Secret** in a secure place. After
|
||||
closing the page, you no longer have access to the secret and can only
|
||||
generate a new one. After you finish registering an app, you can still access
|
||||
and edit the app's other properties.
|
||||
1. Click **Continue to Edit** to configure your app, which is described in the
|
||||
following sections.
|
||||
|
||||
## Configure general information
|
||||
|
||||
Once you've [registered](#register-your-app) your app, you should configure its general information, including:
|
||||
|
||||
- A description, which is visible to everyone in the Roblox community.
|
||||
- A thumbnail image for your app. The recommended file size is at least 150x150
|
||||
pixels.
|
||||
- An **Entry Link** as the entry point of your app, such as the app's website
|
||||
homepage.
|
||||
- A **Privacy Terms URL** and a **Terms of Service URL** for end-users to read
|
||||
before authorizing your app. Each URL must be HTTPS and no more than 256
|
||||
characters.
|
||||
|
||||
<Alert severity="info">
|
||||
You can skip this section during app development and testing, but you must
|
||||
complete it during the review process to publish your app to users.
|
||||
</Alert>
|
||||
|
||||
## Add permissions
|
||||
|
||||
To ensure proper access control and security within your app, you must add
|
||||
**Permission Scopes**. There are two types of permission scopes available:
|
||||
|
||||
- **Identity scopes** for authentication, such as `openid` for user IDs and
|
||||
`profile` for the full profiles. If you select the `profile` scope, you must
|
||||
also select `openid`.
|
||||
- **API-specific permission scopes**, such as `asset:read` for the read
|
||||
permission of assets. Select only the minimum number of scopes that you need
|
||||
for your app.
|
||||
|
||||
<Alert severity="info">
|
||||
Each app is expected to request the minimal number of scopes needed for its function. The set of scopes for an app must fall under a single app category listed in the [Creator Third Party App Policy](https://en.help.roblox.com/hc/en-us/articles/37924211313044-Creator-Third-Party-App-Policy).
|
||||
</Alert>
|
||||
|
||||
## Add redirect URLs
|
||||
|
||||
**Redirect URLs** are the reentry points of your app that users are redirected
|
||||
to when they finish authorizing your app. Ensure your
|
||||
redirect URLs meet the following requirements:
|
||||
|
||||
- All redirect URLs must be in one of the following forms:
|
||||
- Plain HTTPS, for example: `https://www.example.com`.
|
||||
- Paths on localhost with HTTP or HTTPS (self-signed certificate) for local
|
||||
debugging purposes, for example:
|
||||
- `http://localhost:80`
|
||||
- `https://localhost:80`
|
||||
- Custom schemes for specific applications or purposes, for example:
|
||||
- `my-app-scheme:/`
|
||||
- `my-app-scheme://foo/bar/...`
|
||||
- `my-app://action?param1=value1¶m2=value2`
|
||||
- The maximum length of a redirect URL is 256 characters.
|
||||
- You can add up to 10 redirect URLs. With multiple redirect URLs, you can have
|
||||
test environments and allow users to migrate between two sites without
|
||||
downtime.
|
||||
|
||||
<Alert severity="info">
|
||||
You can skip this step during app registration and add the redirect URLs later
|
||||
when you have a testable version of your app.
|
||||
</Alert>
|
||||
|
||||
## Submit for review
|
||||
|
||||
To minimize the chances of malicious apps harming the community, registering an
|
||||
app doesn't make it broadly accessible. Instead, it remains in **private mode**
|
||||
with a limit of 10 unique users. This mode is helpful for testing and
|
||||
debugging within your team.
|
||||
|
||||
If you want to extend the user base for your app, you need to publish it in
|
||||
public mode by submitting it for review:
|
||||
|
||||
1. Go to the [OAuth 2.0 apps](https://create.roblox.com/dashboard/credentials?activeTab=OAuthTab) page.
|
||||
1. Click the **Edit and Publish** button for the app that you want to publish.
|
||||
1. Fill in all the required information and click the **Review and Publish**
|
||||
button. A message with limits on your app permissions during the pending
|
||||
review period appears.
|
||||
1. Click **Submit for Review**.
|
||||
|
||||
While your app review is pending, you can't edit or submit another request until
|
||||
the current review request is approved or rejected. Your app remains in
|
||||
private mode during the review. When your app is approved, it transitions to
|
||||
public mode, and you can't revert it back to private mode.
|
||||
|
||||
Regardless of whether your app is approved or rejected, you receive an email
|
||||
notification of the result when the review is completed.
|
||||
|
||||
## Edit and delete your app
|
||||
|
||||
You can edit or delete your app with the following steps if it's not under
|
||||
review:
|
||||
|
||||
1. Go to the [OAuth 2.0 apps](https://create.roblox.com/dashboard/credentials?activeTab=OAuthTab) page.
|
||||
1. Click **Edit** or **Delete** for the desired app.
|
||||
|
||||
- If you chose to edit an app, follow the same steps and requirements of
|
||||
[registration](#register-your-app).
|
||||
- If you chose to delete an app, click **Yes, Delete** to confirm deletion.
|
||||
After you delete an app, you can't recover it.
|
||||
|
||||
Modifying your app's general information or redirect URLs does not require users
|
||||
to reauthorize the app. However, if you add or modify permission scopes, you
|
||||
must obtain authorization for the new permissions from your users and acquire a
|
||||
new set of tokens. If you don't obtain authorization for the new scopes, your
|
||||
app can continue using the existing tokens, but is limited to the previous
|
||||
scopes.
|
||||
|
||||
For apps in private mode, the system automatically updates your edits with your
|
||||
users. For apps in public mode, you must
|
||||
[submit the app for review](#submit-for-review) again to reflect these changes.
|
||||
Otherwise, the system saves the unpublished changes for you without releasing it
|
||||
to the community.
|
||||
|
||||
<Alert severity ='info'> You can clone a copy of your public app and keep it in
|
||||
private mode for iterative testing and debugging. This allows for a controlled
|
||||
environment where you can safely make changes and resolve any issues before
|
||||
submitting the app for review.</Alert>
|
||||
79
.cursor/rules/roblox/en-us/cloud/auth/oauth2-sample.md
Normal file
79
.cursor/rules/roblox/en-us/cloud/auth/oauth2-sample.md
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
---
|
||||
title: OAuth 2.0 sample app
|
||||
description: Provides a working OAuth 2.0 sample application.
|
||||
---
|
||||
|
||||
Roblox provides a Node.js sample app that shows how to use OAuth 2.0 to let users log in to their Roblox accounts and broadcast messages across their experiences. This app uses the [authorization code flow _without_ PKCE](oauth2-overview.md#grant-types) and is thus only suitable for confidential clients, such as private servers.
|
||||
|
||||
<a href="../../assets/open-cloud/open-cloud-nodejs-sample-oauth2-main.zip">
|
||||
<Button variant="contained">Get the Code</Button>
|
||||
</a>
|
||||
|
||||
<br />
|
||||
|
||||
After downloading the `.zip` file, extract it to its own folder.
|
||||
|
||||
## Register the app
|
||||
|
||||
The first step to setting up the app is to [register it on the Roblox website](oauth2-registration.md) and copy the client ID and secret somewhere safe. Then follow the standard registration steps with these settings:
|
||||
|
||||
1. Under **Permissions**, add the `openid`, `profile`, and `universe-messaging-service:publish` scopes.
|
||||
1. Under **Redirect URLs**, add the `http://localhost:3000/oauth/callback` redirect. If you want to use a non-default port for your app, specify it here.
|
||||
|
||||
## Set environment variables
|
||||
|
||||
Rather than storing them in code (not recommended), the app uses environment variables for your client ID and secret. The process for adding environment variables differs by operating system.
|
||||
|
||||
On Windows, run the following PowerShell commands:
|
||||
|
||||
```powershell
|
||||
$env:ROBLOX_CLIENT_ID='your_client_id_here'
|
||||
$env:ROBLOX_CLIENT_SECRET='your_client_secret_here'
|
||||
$env:ROBLOX_PORT=3000 # Optional. Default is 3000.
|
||||
```
|
||||
|
||||
On Mac and most Linux distributions, run these commands at the terminal:
|
||||
|
||||
```bash
|
||||
export ROBLOX_CLIENT_ID=your_client_id_here
|
||||
export ROBLOX_CLIENT_SECRET=your_client_secret_here
|
||||
export ROBLOX_PORT=3000 # Optional. Default is 3000.
|
||||
```
|
||||
|
||||
If you specified a non-default port in the redirect URL when registering your app, be sure to add the `ROBLOX_PORT` variable.
|
||||
|
||||
<Alert severity="info">
|
||||
These commands only set environment variables for the duration of your terminal session. If you want to load these variables every time you open a new terminal window, add the commands to your shell configuration file, such as `.zshrc` or `.bashrc`. Many hosting services have features to help you add environment variables to your servers.
|
||||
</Alert>
|
||||
|
||||
## Install dependencies
|
||||
|
||||
The app has a handful of dependencies, visible in `package.json`. To install them, run:
|
||||
|
||||
```bash
|
||||
npm ci
|
||||
```
|
||||
|
||||
## Run the app
|
||||
|
||||
To start the app, run:
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
Then navigate to `http://localhost:3000` (or your non-default port) in a web browser.
|
||||
|
||||
The app immediately redirects you to the Roblox login screen, at which point you can log in, verify the permissions that the app is requesting, and click **Confirm and Give Access**.
|
||||
|
||||
Roblox then redirects you back to `localhost`, where you can see that the app now displays some minimal user information, a link back to your profile on Roblox, and fields that you can use to broadcast messages across your experiences.
|
||||
|
||||
### About the app
|
||||
|
||||
In broad strokes, `index.js` performs the following operations:
|
||||
|
||||
1. Starts a new web server using `express`.
|
||||
1. Retrieves the Roblox OpenID Connect (OIDC) configuration, which includes endpoints for authorization, user information, etc. For more information about these endpoints, see [OAuth 2.0 authentication](oauth2-reference.md).
|
||||
1. Creates a new Open ID client using `openid-client` and your stored credentials. This client dramatically simplifies the process of properly forming and sending HTTP requests to the OAuth 2.0 endpoints.
|
||||
1. Defines the routes for the app, including redirects for the login and logout flows and the OAuth 2.0 callback.
|
||||
1. After a successful login, stores the various tokens as cookies, along with some minimal user information that it displays as HTML with help from `getHomeHtml.js`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue