Discord Social SDK
|
The SDK supports two ways of authenticating users:
Also see Account Linking with Discord for a step-by-step guide on setting up account linking with Discord, and Using Provisional Accounts for a step-by-step guide on using provisional accounts with non-Discord authentication providers.
Discord supports the standard OAuth2 flow. You can find our full documentation on our developer portal. But our SDK also provides a few helper methods for you.
If you’re not familiar with OAuth2, some basic background: At a high level the goal of OAuth2 is to allow a user to connect two applications together and share data between them. In this case, allowing a game to access some of their Discord data.
The way this works is the application makes a request to Discord, which will prompt the user, on Discord, to authorize the connection. The user will see what functionality and data the app is requesting, and can approve that request. Once that is done, the user is redirected to a url configured by your application, and that redirect url contains a “code” in it. This code can be exchanged with the other party (in this case Discord), to get back two “tokens”. One of these is an “access token”, which lasts for about 7 days, and can be used to authenticate the user and take actions on their behalf. The other is a “refresh token”, which can be used to generate a new access token after it has expired.
We’ve made two tweaks to the “standard OAuth2” flow though that should help make the experience a lot better for players:
The current version of Discord’s overlay is disabled by default, so that games don’t crash. For testing purposes, you can manually add your game and enable the overlay in your Discord Settings -> Games.
Once you’re ready to launch, we’ll need to verify the overlay works well for your game and add it to a list of overlay-supported games, which will make it enabled by default for users. We’re also working on improvements to remove this requirement.
Also related to the overlay, if your game’s main window is not the same process as the one running the integration you may need to set the window PID using the discordpp::Client::SetGameWindowPid method.
To prevent CSRF attacks during auth, Discord attaches a state
and checks it for you when performing the authorization. You can override state
in the request arguments if you want for your own flow, but please be mindful to keep it a secure, random value.
As mentioned, the SDK will handle OAuth redirects for you. But for this to work, you will need to add http://127.0.0.1/callback
(desktop) and discord-APP_ID:/authorize/callback
(mobile; replace APP_ID with your Discord application id) as a redirect url to your Discord application in the developer portal. You can find that by opening your application on the Discord developer portal and clicking on the OAuth2
tab.
The discordpp::Client::Authorize method is where you'll start. This will kick off the flow by reaching out to Discord, either through our app if it's running or a browser if not, and asking the player to authorize the request to connect.
One of the required arguments to discordpp::Client::Authorize is scopes
, which is the set of permissions that you are requesting. We recommend using discordpp::Client::GetDefaultCommunicationScopes or discordpp::Client::GetDefaultPresenceScopes depending on your use case, but you can choose whatever scopes you need.
After you’ve received approval from the player to access their account, you’ll receive a code
back from our SDK. Depending on your desired destination for account credentials, you may wish to send this code to your backend for processing and storage on a player’s account.
If you don’t have a server, that’s cool too. You'll want to first enable Public Client
on your Discord application's OAuth2 tab on the Discord developer portal. You can then leverage the discordpp::Client::GetToken method to exchange the code for a token using just the client. Codes from this flow can also be used with the account merging flow for provision accounts (explained in detail in a below section).
If you are using discordpp::Client::GetToken, keep in mind that you will be required to specify what is called a “code challenge” and “code verifier” in your requests. We’ll spare you the boring details of how that works (woo… crypto), as we’ve made a simple function to create these for you, discordpp::Client::CreateAuthorizationCodeVerifier.
Once you've received your token, you'll want to set the token in the SDK, you can use discordpp::Client::UpdateToken to do that. At this point, you're authorized and ready to go! You’ll also likely want to store the access token and refresh token for the player somewhere.
Please note that access_token
values do expire. You’ll need to make use of the refresh_token
to refresh the player’s token.
If you are not using the discordpp::Client::GetToken method, you'll need to exchange the code mentioned above with our server on your server. To do that, you'll want to make a request to our API's OAuth2 Token endpoint.
Discord supports the standard OAuth2 device authorization flow.
If you’re not familiar with OAuth2, some basic background: At a high level the goal of OAuth2 is to allow a user to connect two applications together and share data between them. In this case, allowing a game to access some of their Discord data. The way this works is the application makes a request to Discord, which will prompt the user, on console, to scan a QR code or enter a code on Discord. The user will see what functionality and data the app is requesting, and can approve that request. Once that is done, the user is told to go back to the application, and the application will exchange a device code. This code can be exchanged with Discord to get back two “tokens”. One of these is an “access token”, which lasts for about 7 days, and can be used to authenticate the user and take actions on their behalf. The other is a “refresh token”, which can be used to generate a new access token after it has expired.
We’ve made two tweaks to the “standard OAuth2 device authorization” flow though that should help make the experience a lot better for players:
The quickest way to get started is to leverage the discordpp::Client::GetTokenFromDevice method, which will handle the entire process for you. You'll want to first enable Public Client
on your Discord application's OAuth2 tab on the Discord developer portal. You can then leverage the discordpp::Client::GetTokenFromDevice method to exchange the code for a token using just the client.
If you have a server, you'll want to eventually leverage your server to make device + user codes, and then call discordpp::Client::OpenAuthorizeDeviceScreen followed by discordpp::Client::CloseAuthorizeDeviceScreen once authorization has finished.
Once you've received your token, you'll want to set the token in the SDK, you can use discordpp::Client::UpdateToken to do that. At this point, you're authorized and ready to go! You’ll also likely want to store the access token and refresh token for the player somewhere.
Please note that access_token
values do expire. You’ll need to make use of the refresh_token
to refresh the player’s token.
If you are not using the discordpp::Client::GetTokenFromDevice method, you'll need to first obtain the device and user codes mentioned above with our server on your server. To do that, you'll want to make a request to our API's OAuth2 Device Authorization endpoint.
After obtaining these codes, you'll use them to perform device authorization.
First, you'll prompt the user for authorization by calling discordpp::Client::OpenAuthorizeDeviceScreen with the user_code
returned. This will prompt them to scan a QR code or enter a code on a Discord website, which will have them login and authorize your game. You'll also need to start polling at interval
and exchange the returned device_code
with our OAuth2 token endpoint in the exchanging device code section.
If you are not using the discordpp::Client::GetTokenFromDevice method, you'll need to exchange device codes mentioned above with our server on your server after a user has approved the authorization from their device. To do that, you'll want to make a request to our API's OAuth2 Token endpoint.
You'll want to poll this endpoint every interval
until the code expires after expires_in
or succeeds. These values are obtained via the authorize request response above. If the code expires, you'll want to start over with a new authorization request or cancel/close the authorization.
Once you've received your token, you'll want to first close the authorize device screen with discordpp::Client::CloseAuthorizeDeviceScreen and then set the token in the SDK with discordpp::Client::UpdateToken. At this point, you're authorized and ready to go! You’ll also likely want to store the access token and refresh token for the player somewhere.
Please note that access_token
values do expire. You’ll need to make use of the refresh_token
to refresh the player’s token.
Provisional accounts are a way for users that have not signed up for Discord to still access Discord functionality. They are "placeholder" Discord accounts that can be created for the user by the application created earlier. Provisional accounts exist so that your users can engage with Discord APIs and systems without the friction creating their own Discord account.
Instead of using Discord to authenticate these users, we instead rely on the game developer to act as the identity provider and generate an authorization token from that. As such, provisional accounts and their data are unique per Discord application.
Provisional accounts can be migrated or merged into "full" Discord accounts at a later time should the user choose to do that.
Some more miscellaneous details:
In order to use provisional accounts, you will need some additional configuration on the application created earlier. You’ll need to configure which identity provider you want to use to create provision accounts from. Currently, Discord supports OIDC, Steam session tickets, or EOS access/id tokens.
There is no way to configure this in the developer portal yet, so reach out to us with the following information when ready:
<issuer_url>/.well-known/openid-configuration
, as described in the OIDC specificationissuer
, authorization_endpoint
, token_endpoint
, jwks_uri
, and id_token_signing_alg_values_supported
authorization_endpoint
and token_endpoint
aren’t actually used by Discord but are required by spec. If you want to put placeholder values here it wouldn’t harm your ability to use the provisional accounts feature. We may remove this requirement in the future.issuer
, authorization_endpoint
, token_endpoint
, jwks_uri
are all expected to be https urls (including placeholders). RS256
, RS384
, RS512
, ES256
, ES384
, ES512
, PS256
, PS384
, PS512
aud
field in the JWTProvisional accounts are authenticated via external credentials like OIDC ID tokens, Steam session tickets, or EOS access/id tokens. We're also exploring other providers, so please reach out if you need something different!
Using these credentials, we'll create a limited Discord just for your game and try to set the username for you according to the following:
preferred_username
claim, if specified in the ID token. This field is optional and should be between 1 and 32 characters. If not specified, the user’s display name will default to the user’s unique username, which is generated by Discord on creation. The quickest way to get started is to leverage the discordpp::Client::GetProvisionalToken method, which will handle the entire process for you. You'll want to first enable Public Client
on your Discord application's OAuth2 tab on the Discord developer portal. You can then leverage the discordpp::Client::GetProvisionalToken method for a token using just the client.
If you have a server, you'll want to eventually leverage your server to exchange these external credentials for a provisional account token.
Once you've received your token, you'll want to set the token in the SDK, you can use discordpp::Client::UpdateToken to do that. At this point, you're authorized and ready to go! It is suggested that these provisional tokens are not stored, since they have short TTLs. Once expired you'll need to obtain a new one.
If you are not using the discordpp::Client::GetProvisionalToken method, you'll need to make a request to our API's provisional account token endpoint.
External Auth Type | Value of the External Auth Token |
---|---|
OIDC | OpenID Connect ID token. |
STEAM_SESSION_TICKET | A Steam auth ticket for web generated with discord as the identity . |
EPIC_ONLINE_SERVICES_ACCESS_TOKEN | Access token for Epic Online Services. Supports EOS Auth access tokens. |
EPIC_ONLINE_SERVICES_ID_TOKEN | ID token for Epic Online Services. Supports both EOS Auth + Connect ID tokens. |
Error Code | Description |
---|---|
530000 | Your Discord application has not been granted the permission to use provisional accounts. |
530001 | The ID token JWT you have provided is expired. You will need to get another one issued from the identity provider. |
530002 | The issuer in the ID token JWT you have provided does not match what you have configured. |
530003 | The audience in the ID token JWT you have provided does not match the audience you specified in your OIDC configuration. Either update your configuration or pass in an ID token that was issued to your application. |
530004 | The ID token you provided was issued too long ago. Discord will not accept ID tokens issued beyond a week ago. You will need to get a new ID token issued from the identity provider. |
530006 | Discord failed to generate a unique username within the allotted time. This is not a terminal error, and should resolve itself upon a retry. |
530007 | Your client secret is invalid. Double check what you are sending or regenerate your client secret. |
The quickest way to refresh tokens is to leverage the discordpp::Client::RefreshToken method, which will handle the entire process for you. You'll want to first enable Public Client
on your Discord application's OAuth2 tab on the Discord developer portal. You can then leverage the discordpp::Client::RefreshToken method for a token using just the client.
If you have a server, you'll want to eventually leverage your server to exchange these external credentials for a provisional account token.
If you are not using the discordpp::Client::RefreshToken method, you'll need to make a request to our API's token endpoint to refresh tokens.
If you'd like to revoke access or refresh tokens for any reason (they were compromised, the user wishes to disconnect), you can send a request to the token revocation endpoint. If any valid access or refresh token is revoked, all of your game's access and refresh tokens for the user are immediately revoked.
Provisional accounts can be “upgraded” to full Discord accounts through a merge process, and provisional accounts can be “downgraded” from a full Discord account through an unmerge process. The following sections describe how to use these features.
The quickest way to merge accounts is to leverage the discordpp::Client::GetTokenFromProvisionalMerge (Desktop & Mobile) or discordpp::Client::GetTokenFromDeviceProvisionalMerge (Console) method, which will handle the entire process for you. You'll want to first enable Public Client
on your Discord application's OAuth2 tab on the Discord developer portal. You can then leverage the discordpp::Client::GetTokenFromProvisionalMerge or discordpp::Client::GetTokenFromDeviceProvisionalMerge method using just the client.
If you have a server, you'll want to eventually leverage your server for the merge operation.
If you are not using the discordpp::Client::GetTokenFromProvisionalMerge or discordpp::Client::GetTokenFromDeviceProvisionalMerge method, you'll need to make a request to our API's OAuth2 token endpoint from your server.
A user can unmerge their account by removing access to your application on their Discord User Settings -> Authorized Apps page.
A developer can unmerge a user's account by sending a request to the unmerge endpoint on our API.
Discord provides the option to associate a game identity with a Discord account even if there is no existing provisional account. An example use case for this may be that you are using provisional accounts, but you want to present a “link with Discord” prompt before a provisional account has been created for that game identity and, as a result, enforce a uniqueness constraint on Discord accounts by external identity for your game.
To associate a Discord account with a game identity, you can leverage the merge provisional account operations listed above in lieu of normal authorization token exchange operations. Because there is no existing provisional account associated with the provided game identity, the merge operation is skipped.