← Hub developers

Sign in with Rankly

Permetti agli utenti Rankly di accedere alla tua app con il loro account Rankly. Implementa OAuth 2.0 + OpenID Connect standard contro gli endpoint pubblicati su Rankly. Niente librerie custom: qualsiasi client OIDC funziona out-of-the-box.

1. Cos'è e quando usarlo

Sign in with Rankly è un OAuth 2.0 + OpenID Connect provider gestito da Rankly. Usalo quando:

  • Vuoi permettere agli utenti Rankly di loggarsi nella tua app senza creare un secondo account.
  • Vuoi leggere/scrivere dati Rankly a nome di un utente specifico (rispettando i suoi permessi sulle org di cui è membro).
  • Stai costruendo un bot Discord, un overlay caster, un'app mobile, una dashboard custom che deve agire come quell'utente.

Per integrazioni server-to-server senzaun utente specifico (es. job notturno che legge tutti i tornei di un'org), usa invece le API key Bearer: sono org-bound, più semplici, e non richiedono il flow utente.

2. Registrare la tua app

Self-service: se sei admin/owner di un'organizzazione Rankly, registri il client da Account → Organizzazione → App OAuth in pochi secondi. Ottieni client_id (pubblico) + client_secret (segreto, mostrato una sola volta).

Devi indicare:

  • Nome app (quello che l'utente vede sulla pagina di consenso).
  • Tipo: web (backend server-side con client_secret), public (SPA/native con PKCE solo), native, user-agent-based.
  • Redirect URI(s): l'URL della tua app dove Rankly rispedirà l'utente dopo il consenso. https:// obbligatorio (eccetto http://localhost per dev).

Conserva il client_secret nel password manager / vault del tuo deploy. Il secret non è recuperabile: se lo perdi, cancella il client e creane uno nuovo.

3. Discovery URL

Tutto parte da qui. Il discovery URL espone gli endpoint, gli algoritmi supportati e la JWKS URI in formato JSON standard OIDC:

GET https://api.rankly.it/api/auth/.well-known/openid-configuration

Qualsiasi libreria OIDC moderna (openid-client per Node.js, Authlib per Python, AppAuth per mobile) lo legge in automatico. Non serve hardcodare gli URL dei singoli endpoint.

4. Authorization Code Flow

È il flow standard server-side. Per SPA/native usa la variante con PKCE (S256 supportato).

Step 1 — redirect a Rankly

La tua app costruisce l'URL di authorize e ci spedisce l'utente:

https://api.rankly.it/api/auth/oauth2/authorize?
  response_type=code
  &client_id=<YOUR_CLIENT_ID>
  &redirect_uri=<YOUR_REDIRECT_URI>
  &scope=openid profile email tournaments:read
  &state=<RANDOM_STRING_FOR_CSRF>
  &code_challenge=<PKCE_S256_CHALLENGE>   # se PKCE
  &code_challenge_method=S256             # se PKCE

Rankly verifica la session utente: se non è loggato, lo manda a /signin. Una volta loggato, mostra la pagina di consenso con i tuoi scope tradotti in italiano. L'utente preme Autorizza → Rankly redirige al tuo redirect_uri con:

<YOUR_REDIRECT_URI>?code=<AUTH_CODE>&state=<TUO_STATE>

Importante: verifica che state coincida con quello che hai mandato (CSRF guard).

Step 2 — scambio code → token

Lato server (mai dal browser per i client web):

POST https://api.rankly.it/api/auth/oauth2/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic base64(client_id:client_secret)

grant_type=authorization_code
&code=<AUTH_CODE>
&redirect_uri=<YOUR_REDIRECT_URI>
&code_verifier=<PKCE_VERIFIER>   # se PKCE

Risposta:

{
  "access_token": "...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "...",
  "id_token": "eyJhbGciOiJSUzI1NiIs...",
  "scope": "openid profile email tournaments:read"
}

Esempio Node.js (openid-client)

import { Issuer } from 'openid-client';

const issuer = await Issuer.discover('https://api.rankly.it/api/auth');
const client = new issuer.Client({
  client_id: process.env.RANKLY_CLIENT_ID,
  client_secret: process.env.RANKLY_CLIENT_SECRET,
  redirect_uris: ['https://your-app.com/auth/callback'],
  response_types: ['code'],
});

// Step 1: redirect
const url = client.authorizationUrl({
  scope: 'openid profile email tournaments:read',
  state,
});

// Step 2 (route /auth/callback):
const params = client.callbackParams(req);
const tokenSet = await client.callback(redirectUri, params, { state });
const userinfo = await client.userinfo(tokenSet.access_token);
// userinfo => { sub, name, email, ... }

Esempio cURL

# Step 2 dopo aver ricevuto ?code=XYZ
curl -X POST https://api.rankly.it/api/auth/oauth2/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d "grant_type=authorization_code" \
  -d "code=XYZ" \
  -d "redirect_uri=https://your-app.com/auth/callback"

5. Scope disponibili

  • openid — obbligatorio per OIDC, identifica l'utente (sub claim).
  • profile — accesso a username, nome.
  • email — accesso all'email.
  • offline_access — emette refresh_token, permette di rinnovare l'access_token senza re-login.
  • tournaments:read — chiamate GET su /api/v1/orgs/{orgId}/tournaments e affini, nei limiti delle membership dell'utente.
  • tournaments:write — chiamate POST/PATCH/DELETE su tornei, match, participants. Richiede membership admin/owner dell'org target.

Chiedi solo gli scope che usi davvero. Più scope chiedi, più la pagina di consenso risulta intrusiva, meno utenti accettano.

6. Profilo utente

GET https://api.rankly.it/api/auth/oauth2/userinfo
Authorization: Bearer <access_token>

Risposta:

{
  "sub": "usr_xxx",
  "name": "Andrea Gasloli",
  "preferred_username": "gas",
  "email": "andrea@example.com",
  "email_verified": true
}

7. Chiamate API a nome utente

L'access_tokenemesso vale anche come Bearer per l'API REST di Rankly https://api.rankly.it/api/v1/*:

curl https://api.rankly.it/api/v1/orgs/<orgId>/tournaments \
  -H "Authorization: Bearer <access_token>"

Regole:

  • Membership check: il backend verifica che l'utente sia member dell'org target. Se non lo è → 403 oauth_user_not_member.
  • Scope check: le mutation richiedono tournaments:write. Le read richiedono tournaments:read implicito o esplicito.
  • Ereditarietà admin: se l'utente è admin/owner di una federazione, può accedere a tutti i club affiliati (sub-org) senza membership esplicita su ciascuno.
  • Subscription: l'org target deve avere sub trialing o active. Altrimenti read sono ok, write → 402 subscription_required.

8. Refresh token

Se hai chiesto lo scope offline_access, ricevi un refresh_tokeninsieme all'access_token. Usalo per rinnovare:

POST https://api.rankly.it/api/auth/oauth2/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic base64(client_id:client_secret)

grant_type=refresh_token
&refresh_token=<REFRESH_TOKEN>

Durata di default: access_token 1 ora, refresh_token 7 giorni. Rotation: ogni refresh emette un nuovo refresh, il precedente viene invalidato (rotazione standard OIDC).

9. Verifica id_token (JWKS)

Gli id_token sono JWT firmati RS256. Verifica la firma offline scaricando la chiave pubblica da:

GET https://api.rankly.it/api/auth/jwks

Le librerie OIDC fanno questa verifica in automatico (jose, jsonwebtoken con jwks-rsa, ecc). La rotazione delle chiavi è gestita lato Rankly: il kidnell'header del JWT indica quale chiave usare.

# Esempio con jose (Node.js)
import { createRemoteJWKSet, jwtVerify } from 'jose';

const JWKS = createRemoteJWKSet(
  new URL('https://api.rankly.it/api/auth/jwks'),
);
const { payload } = await jwtVerify(idToken, JWKS, {
  issuer: 'https://api.rankly.it',
  audience: process.env.RANKLY_CLIENT_ID,
});

10. Errori comuni

Sul flow OAuth

  • invalid_client: client_id non trovato o client_secret sbagliato. Verifica le credenziali.
  • invalid_grant: code già scambiato (single-use), scaduto (10 min), o redirect_uri diverso da quello del request.
  • unauthorized_client: il tuo client non è autorizzato a usare quel grant_type. Per web ok auth_code+refresh, per public solo auth_code+PKCE.
  • Redirect dopo consenso fallisce: probabile redirect_uri non whitelisted in fase di registrazione.

Sull'API call

  • 401 invalid_token: access_token scaduto o revocato dall'utente. Usa il refresh_token.
  • 401 token_expired: come sopra.
  • 403 oauth_user_not_member: l'utente non è member dell'org target.
  • 403 scope_required:tournaments:write: mancano scope per la mutation. Richiedi tournaments:write nello scope iniziale.
  • 402 subscription_required: l'org target non ha subscription attiva.

Contatto + revoca lato utente

Email tecnico: support@rankly.it. Risposta in italiano entro 1 giorno lavorativo.

Lato utente: gli utenti Rankly vedono le tue app autorizzate su /account/oauth-authorizationse possono revocarle in qualsiasi momento. Dopo la revoca, l'utente dovrà riautorizzare la tua app dal flusso /authorize standard.