Depends. Thats for example based on holidays in the US and other factors that could affect the review time for applications. Also there is a difference between a raw RSO apply for LOL and a full production key apply for valorant for example, the second one could potential take longer then the first option. The range can be 12 hours up to 3-4 months
(You have to send that information after your RSO got accepted, so make sure you have preperared the following things)
- Contact Emails
- Name of the company/service
- Will also appear on the RSO Login Page
- Logo of the company/service
- Should scale between 275x275 and 60x60
- Suggested is an SVG, but PNG will also work
- Will be displayed on light and dark backgrounds (see examples below)
- Privacy policy URL
- Terms of service URL
- Redirect URLs
- A list of URLs you would like the RSO Client to redirect the players after login
- Typically a callback which is used to get information about the player who logged in
- Post Logout Redirect URLs
- A list of URLs you would like the RSO Client to redirect the players after logout
- Preffered ClientId
- Unique name for your product without punctation or spaces
- You will receive a link to gather your
client secret
or yourclient_assertion
- This link will expire after 6 days after you got the mail or after three times opening the link
- This link is secured with a basic auth, the credentials for this will be also in the mail
Endpoint | Description |
---|---|
GET https://auth.riotgames.com/authorize | Endpoint for obtaining an authorization code |
POST https://auth.riotgames.com/token | Endpoint to exchange authorization codes for access, identity, and refresh tokens |
GET https://auth.riotgames.com/jwks.json | Endpoint to grab JSON Web Keys for verifying the authenticity of access and identity tokens |
GET https://auth.riotgames.com/userinfo | Endpoint to use your access token to obtain user information |
GET https://{cluster}.api.riotgames.com/riot/account/v1/accounts/me | Endpoint for optaining gameName, tagLine and PUUID for VALORANT and Legends of Runeterra. Note: The data that is returned from each cluster is identical. Use the cluster closest to your handling server. Clusters: americas, europe, asia. Docs: Link |
GET https://{cpid}.api.riotgames.com/lol/summoner/v4/summoners/me | Endpoint for optaining accountId, profileIconId, revisionDate, name, id, puuid and summonerLevel for for League Of Legends. Note: You have to include the cpid scope in the login url. You can optain the cpid by doing a request to the userinfo endpoint. Docs: Link |
GET https://{cpid}.api.riotgames.com/tft/summoner/v1/summoners/me | Endpoint for optaining accountId, profileIconId, revisionDate, name, id, puuid and summonerLevel for for Teamfight Tactics. Note: You have to include the cpid scope in the login url. You can optain the cpid by doing a request to the userinfo endpoint. Docs: Link |
After the player logged in with the correct credentials, they are automaticly redirected to the redirect_uri
you specified, together with an authorization code as a query string in the url.
This code can be sent to the token
endpoint to receive access, identity, and refresh tokens.
The access token you receive from this endpoint can be then used to get more sensitive data like summoner information, locale, puuid and some more stuff
Here are the fields you can or have to include in your RSO URL
Field | Description | Optional |
---|---|---|
redirect_uri | OAuth 2 Callback route you have to set up at your own server. This route needs to be able to process a code query parameter that is added to the URI on when Riot Sign On redirects the player back to our URI. We must also be sure we have this URI added as one of the redirect_uris during client registration See Bullet Point 6 here | ❌ |
client_id | ID assigned to client during registration. This will be the Client ID you got when you registered a client See Bullet Point 8 here | ❌ |
response_type | Response type expected, should be code for authorization code flow | ❌ |
scope | A predefined data scope, must include openid to authenticate and cpid if you use RSO for LoL or TfT |
❌ |
ui_locales | Space-separated list of player’s preferred BCP47 language tag values in order of most to least preferred | ✅ |
state | An opaque value provided to the authorize endpoint. The same value is returned to you when the endpoint sends its reply. Enables you to compare value sent and received, to prevent CSRF | ✅ |
prompt | Can only be "login". Will show the login page where you can switch accounts or have to login again with your password | ✅ |
Here are the additional scopes you can use
Field | Description | Optional | Useable? |
---|---|---|---|
cpid | Return the game region for League of Legends | ✅ | ✅ |
offline_access | Allows refresh tokens to be used to retrieve new access_tokens that have access to the /userinfo endpoint | ✅ | ✅ |
account | ??? | ✅ | ❌ |
Returns the email of the account | ✅ | ❌ | |
profile | ??? | ✅ | ❌ |
If you add all fields that are needed together you will get the following result:
https://auth.riotgames.com/authorize?redirect_uri=http://example.com/callback&client_id=exampleclientid&response_type=code&scope=openid
When the player successfully logs in, a 302 Redirect sends their browser to the redirect_uri
that you included in your Sign In link.
This route receives a code as a url query-string parameter, and the server must then make a server-to-server request to exchange this code for access, identity, and refresh tokens. We’ll need to send a few things to Riot Sign On’s token endpoint to get these tokens back. The endpoint which is used here is the token
endpoint.
Field | Value | Description |
---|---|---|
Authorization | "Basic " + Base64Encode(client_id + ":" + client_secret) | Authorization Header |
grant_type (Form Data) | "authorization_code" | Grant type |
code (Form Data) | Individual per request (is a string) | RSO access code, which we received as a querystring parameter to our oauth2-callback route |
redirect_uri (Form Data) | Same redirect URL that is passed in the login link | RSO access code, which we received as a querystring parameter to our oauth2-callback route |
Sample Response
{
"scope":"openid",
"expires_in":600,
"token_type":"Bearer",
"refresh_token":"dXJuOnJpb3Q6cOk1qdNal...8zN3NzbQ.xw96rZeGEMtrFlDCGLyA",
"id_token":"eyJhbGciJSUzI1mtpZCInMxIn0...YiI6InVybjpyaW90OpZDp2MTpNalV",
"sub_sid":"vldfsXGdDPoafSKfjS932cslKu8JDUKZ-woZvXDoq8",
"access_token":"eyJhbGciOi1NsImZCI6InM...NTkzMTA3LCJjaWQiJnmE-BVnZbYqY"
}
Explanation of all fields from the response
Field | Description |
---|---|
scope | Details what level of access the given Access Token provides. See the scopes list for more information |
expires_in | Life span of the access token |
token_type | Method of authorization token provides. Bearer means the entire token should be provided |
sub_sid | The identifier of an existing session (SID) for the subject (player) |
access_token | Undecryptable JWT Token. Used for scoped authentication of a client and player to a resource |
id_token | Decryptable JWT Token. Provides information to authenticate a player’s identity |
refresh_token | Issued for the purpose of obtaining new access tokens when an older one expires |
POST https://auth.riotgames.com/token
Headers:
- None needed
Form Data:
- client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
- client_assertion: SIGNED-JWT-HERE
- grant_type: "authorization_code"
- redirect_uri: REDIRECT-URL-HERE
- code: CODE-FROM-QUERY-STRING-HERE
JavaScript WebServer Example
const axios = require('axios');
const fastify = require('fastify')();
const example_client_assertion = 'SIGNED-JWT-HERE';
fastify.get('/api/v1/rso/login', async (req, res) => {
const formData = new URLSearchParams();
formData.append('client_assertion_type', 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer');
formData.append('client_assertion', example_client_assertion);
formData.append('grant_type', 'authorization_code');
formData.append('code', req.query.code);
formData.append('redirect_uri', 'https://example.com/api/v1/rso/login');
const tokens = await axios.post('https://auth.riotgames.com/token', formData).catch(error => console.error(error));
console.log(tokens.data);
});
fastify.listen(3000, () => {
console.log('API Online');
});
POST https://auth.riotgames.com/token
Headers:
- Authorization: "Basic + Base64Encode(client_id + ":" + client_secret)"
Form Data:
- grant_type: "authorization_code"
- code: CODE-FROM-QUERY-STRING-HERE
- redirect_uri: REDIRECT-URL-HERE
JavaScript WebServer Example
const axios = require("axios")
const fastify = require("fastify")()
const examplesecret = "000000000000000000000"
fastify.get("/api/v1/rso/login", async (req, res) => {
const formData = new URLSearchParams()
formData.append('grant_type', "authorization_code")
formData.append('code', req.query.code)
formData.append('redirect_uri', "https://example.com/api/v1/rso/login")
const tokens = await axios.post("https://auth.riotgames.com/token", formData, {
headers: {
"Authorization": `Basic ${Buffer.from(`exampleclientid:${examplesecret}`).toString("base64")}`
}
}).catch(error => console.error(error))
console.log(tokens.data)
})
fastify.listen(3000, () => {console.log("API Online")})
Response
{
"scope":"openid",
"expires_in":600,
"token_type":"Bearer",
"refresh_token":"dXJuOnJpb3Q6cOk1qdNal...8zN3NzbQ.xw96rZeGEMtrFlDCGLyA",
"id_token":"eyJhbGciJSUzI1mtpZCInMxIn0...YiI6InVybjpyaW90OpZDp2MTpNalV",
"sub_sid":"vldfsXGdDPoafSKfjS932cslKu8JDUKZ-woZvXDoq8",
"access_token":"eyJhbGciOi1NsImZCI6InM...NTkzMTA3LCJjaWQiJnmE-BVnZbYqY"
}
Notes
None
POST https://auth.riotgames.com/token
Headers:
- Authorization: "Basic + Base64Encode(client_id + ":" + client_secret)"
Form Data:
- grant_type: "refresh_token"
- refresh_token: TOKEN_HERE
- scope (optional): SCOPE-LIST
JavaScript WebServer Example
const axios = require("axios")
const refresh_token = "000000000000000000000"
const formData = new URLSearchParams()
formData.append('grant_type', "refresh_token")
formData.append('refresh_token', refresh_token)
const tokens = await axios.post("https://auth.riotgames.com/token", formData, {
headers: {
"Authorization": `Basic ${Buffer.from(`exampleclientid:${examplesecret}`).toString("base64")}`
}
}).catch(error => console.error(error))
console.log(tokens.data)
Response
{
"scope":"openid",
"expires_in":600,
"token_type":"Bearer",
"refresh_token":"dXJuOnJpb3Q6cGlkOn...amNvaG8zN3NzbQeGEmeMtrFlDCGLyA",
"access_token":"eyJhbGciOiJSUzI1NiI...sFwkadLmWmwtvJouhX22Tc6vPnfXTk"
}
Notes
When using a refresh token, there are two actions RSO may take.
If it replies with a new refresh token, it must be used in all future access token refreshes and the previous refresh token is now invalid.
If the same refresh token is received in the response, you may continue to use it in future refresh requests.
Included in the [Using Token Endpoint](#using-tokens-endpoint) response. No requested needed.
JavaScript WebServer Example
const axios = require("axios")
const fastify = require("fastify")()
const examplesecret = "000000000000000000000"
fastify.get("/api/v1/rso/login", async (req, res) => {
const formData = new URLSearchParams()
formData.append('grant_type', "authorization_code")
formData.append('code', req.query.code)
formData.append('redirect_uri', "https://example.com/api/v1/rso/login")
const tokens = await axios.post("https://auth.riotgames.com/token", formData, {
headers: {
"Authorization": `Basic ${Buffer.from(`exampleclientid:${examplesecret}`).toString("base64")}`
}
}).catch(error => console.error(error))
const userdata = JSON.parse(Buffer.from(tokens.data.id_token.split('.')[1], "base64"))
})
fastify.listen(3000, () => {console.log("API Online")})
Response
{
"sub": "000000000000000000000000000000000000000000000000000000000000000000000000000000",
"aud": "exampleclientid",
"acr": "urn:riot:bronze",
"amr": [ "google_auth" ],
"iss": "https://auth.riotgames.com",
"exp": 1645963629,
"locale": "de_DE",
"iat": 1645877229
}
Notes
None
https://beta.developer.riotgames.com