BeatLeader Authentication
For this app, I explored three ways to access your BeatLeader data: Steam, OAuth, or a website‑style session.
I wanted tools like Compare Players to show unranked star ratings when your BeatLeader account is a supporter and ShowAllRatings is enabled. That turns out to not be possible without implementing Steam ticket handling using the Steamworks SDK. The rest of the notes here were written before I realized that.
Default API auth is Steam. You can override per request using ?auth=steam|oauth|session|auto|none.
Steam Login
Authenticate via Steam OpenID to link your Steam account. Then use the BeatLeader Auth Tool with your Steam session ticket to capture a website session.
OAuth Login
scp:profileto read your user profile.scp:offline_accessto refresh your session without re‑prompting (optional).
You can still login with OAuth when needed: Login with BeatLeader (OAuth)
After OAuth login, we attempt to enable ShowAllRatings automatically. If your BL account is not a supporter, BL will ignore it.
Session Login (Website‑style)
Most users authenticate on the BeatLeader website using Steam. Use the BeatLeader Auth Tool to submit a Steam session ticket; we’ll create a BL website session for server‑side calls where OAuth is not honored.
The current session status is available via GET /api/beatleader/oauth/status as hasSession.
Requirements to see unranked star ratings
- You must authenticate with a user identity that BeatLeader recognizes for profile flags like
ShowAllRatings. For the endpoints listed below, this currently means a website session cookie, not an OAuth bearer. - Your BeatLeader account must be a supporter (tipper/supporter/sponsor).
- Your BL profile setting
ShowAllRatingsmust be enabled. We auto‑enable it after login; if you're not a supporter, BL will ignore it.
OAuth tokens vs. website session for scores/stars
Some read endpoints on BeatLeader currently do not honor OAuth bearer tokens for determining the current user, and instead rely on the cookie‑authenticated website session:
GET /player/{id}/scoresGET /leaderboards/hash/{hash}
For these endpoints, an OAuth Authorization: Bearer ... header will not affect user‑specific visibility like ShowAllRatings. They read the user from the website session cookie. In our debug panel this appears as Using auth: oauth with Last Cookie: absent — and unranked stars may be hidden even if your account is eligible.
Workarounds
- Use a website session: Use the BeatLeader Auth Tool with your Steam session ticket. We store the BL session cookie and attach it to server calls. Debug will show Using auth: session and Last Cookie: present.
- Force session for a request: Append
?auth=sessionto our API URLs to prefer website session over OAuth for that call. Example:/api/beatleader?path=/leaderboards/hash/{hash}&auth=session. - Prefer session when both exist: Our tools default to
?auth=auto(use OAuth if present, then session). If you have both and need session for these endpoints, explicitly pass?auth=sessionor temporarily sign out OAuth at /auth/beatleader/logout.
Other endpoints (e.g., /oauth2/identity, some write operations, and endpoints that explicitly check OAuth scopes) do honor OAuth bearer tokens. This limitation is specific to a few read endpoints listed above.
OAuth App Setup (for developers)
- Configure BeatLeader OAuth credentials here:
BL OAuth Setup. If you already have credentials, you can paste them there. - Use the OAuth Login above; we request
scp:offline_accessto allow refresh without re‑prompting.
Multi‑environment setup: If you deploy to multiple environments (dev, staging, production), you must register all redirect URIs in your BeatLeader OAuth application. For example: http://localhost:5173/auth/beatleader/callback, https://staging.example.com/auth/beatleader/callback, and https://example.com/auth/beatleader/callback. The app automatically uses the correct redirect URI based on the current environment's origin.
How this app uses your auth
- Default auth mode is Steam. You can override per‑request with
?auth=steam|oauth|session|auto|none. - Server routes use your OAuth token when available; otherwise some endpoints fall back to your BL session cookie:
/api/beatleader?path=/usersupports OAuth token or session cookie./api/beatleader/user/profile(PATCH) uses OAuth token or session cookie to toggle flags likeShowAllRatings.- Other public GETs are proxied unauthenticated or with your token when relevant.
- Other tools call these endpoints and will include unranked stars if your user auth allows it and
ShowAllRatingsis enabled.
Desktop app (Tauri) implementation plan
The desktop build of this app will automatically obtain a Steam session ticket using the Steamworks SDK and create your BeatLeader website session without manual input. High‑level plan:
- Integrate Steamworks in Tauri: add Steamworks SDK and implement a Tauri command (e.g.,
getSteamSessionTicket) that callsISteamUser.GetAuthSessionTicketand returns the ticket string. - Wire the ticket endpoint: make
GET /api/steam/ticketcall the Tauri command. Until Tauri is in place, it supports a local helper viaBL_STEAM_TICKET_CMDthat outputs a ticket to stdout. - Create BL website session: the tool at BeatLeader Auth Tool fetches the Steam ticket and then POSTs it to
/auth/beatleader/steam-ticket(forwards toapi.beatleader.com/signinwithprovider=steamTicket). We capture BL cookies server‑side. - Verify:
GET /api/beatleader/oauth/statusshould reporthasSession: true. - Use session for specific endpoints: For
/player/{id}/scoresand/leaderboards/hash/{hash}(where OAuth is ignored), call our proxy with?auth=sessionor keep?auth=autowhen no OAuth token is present.
Security note: the Steam session ticket is used only to establish a BeatLeader website session and is never stored. We store only the BL cookies (httpOnly) necessary for server‑side requests.
Why connect?
- Compare Players can show BeatLeader star ratings alongside map tiles.
- If your BL account grants visibility into unranked stars, those will appear too.
Technical Details
For developers curious about the implementation, here's how BeatLeader's OAuth2.0 system works:
BeatLeader Server (Backend)
BeatLeader uses OpenIddict as its OAuth2.0/OpenID Connect server implementation. The token creation is handled automatically by OpenIddict rather than custom code.
Key Components:
- Token Endpoint:
/oauth2/token- Handled automatically by OpenIddict - Authorization Endpoint:
/oauth2/authorize- Custom controller inAuthenticationController.cs - User Info Endpoint:
/oauth2/identity- Returns user profile data - Client Management:
/developer/app*- OAuth application registration and management
Authorization Flow:
- GET /oauth2/authorize: Renders consent screen and validates user authentication
- POST /oauth2/authorize: Processes user consent and creates authorization code via
SignIn() - POST /oauth2/token: OpenIddict automatically exchanges authorization code for access/refresh tokens
Configuration (Startup.cs):
options.SetAuthorizationEndpointUris("oauth2/authorize")
.SetTokenEndpointUris("oauth2/token")
.SetUserinfoEndpointUris("oauth2/identity");
options.AllowAuthorizationCodeFlow()
.AllowRefreshTokenFlow(); BeatLeader Website (Frontend)
The website provides the OAuth consent UI and developer portal, but delegates all token operations to the API.
Key Components:
- Consent Screen:
OauthSignIn.svelte- Renders the authorization approval UI - Developer Portal:
DeveloperPortal.svelte- OAuth application management - App Management:
OauthApp.svelte- Create/edit OAuth applications
Authorization Flow:
- Consent UI: Posts to
BL_API_URL + 'oauth2/authorize'with user approval - Client Info: Fetches app details from
BL_API_URL + 'oauthclient/info' - CSRF Protection: Uses antiforgery tokens from
BL_API_URL + 'oauthclient/antiforgery'
Developer Portal Features:
- OAuth application registration with custom client IDs
- Scope management (profile, clan, offline_access)
- Redirect URL configuration
- Client secret generation and reset
- Test authorization URL generation
OAuth Flow Summary
- Client redirects user to
/oauth2/authorizewith client_id, scope, response_type=code - BeatLeader validates user authentication and renders consent screen
- User approves → authorization code generated via OpenIddict
- Client exchanges code for tokens at
/oauth2/token(handled by OpenIddict) - Client uses access token for API calls, refresh token for renewal
Security Features
- CSRF Protection: Antiforgery tokens on consent forms
- Scope Validation: Only requested scopes are granted
- Client Validation: Registered applications only
- Token Security: Signed/encrypted tokens with X.509 certificates
- Authorization Storage: Permanent authorizations to avoid repeated consent
Sign out
- Everything:
POST /auth/beatleader/logout-all(clears OAuth tokens and session) - Only OAuth tokens: visit
/auth/beatleader/logout - Only session cookie:
POST /auth/beatleader/session/logout
curl -X POST 'https://{your-host}/auth/beatleader/logout-all' Troubleshooting
- Unranked stars missing: confirm you’re logged in with a supporter BL account and that
ShowAllRatingsis enabled. - Check connection:
GET /api/beatleader/oauth/statusshowsconnected,hasCreds, andhasSession. - Re‑login: use OAuth at
/auth/beatleader/loginor submit a fresh Steam session ticket in the BeatLeader Auth Tool. - If the debug panel shows Using auth: oauth and Last Cookie: absent on
/player/{id}/scoresor/leaderboards/hash/{hash}, force session with?auth=sessionand ensure your website session is active via the tool. - Redirect mismatch: ensure your app’s redirect in BL developer portal matches
{origin}/auth/beatleader/callback.