BeatLeader Authentication

Educational use only: The information and resources on this page are for learning purposes. Do not use them for real authentication or accessing accounts.

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.

Steam
Not linked
OAuth
Not connected
Website Session
Not active

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:profile to read your user profile.
  • scp:offline_access to 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 ShowAllRatings must 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}/scores
  • GET /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=session to 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=session or 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)

  1. Configure BeatLeader OAuth credentials here: BL OAuth Setup. If you already have credentials, you can paste them there.
  2. Use the OAuth Login above; we request scp:offline_access to 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=/user supports OAuth token or session cookie.
    • /api/beatleader/user/profile (PATCH) uses OAuth token or session cookie to toggle flags like ShowAllRatings.
    • 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 ShowAllRatings is 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:

  1. Integrate Steamworks in Tauri: add Steamworks SDK and implement a Tauri command (e.g., getSteamSessionTicket) that calls ISteamUser.GetAuthSessionTicket and returns the ticket string.
  2. Wire the ticket endpoint: make GET /api/steam/ticket call the Tauri command. Until Tauri is in place, it supports a local helper via BL_STEAM_TICKET_CMD that outputs a ticket to stdout.
  3. Create BL website session: the tool at BeatLeader Auth Tool fetches the Steam ticket and then POSTs it to /auth/beatleader/steam-ticket (forwards to api.beatleader.com/signin with provider=steamTicket). We capture BL cookies server‑side.
  4. Verify: GET /api/beatleader/oauth/status should report hasSession: true.
  5. Use session for specific endpoints: For /player/{id}/scores and /leaderboards/hash/{hash} (where OAuth is ignored), call our proxy with ?auth=session or keep ?auth=auto when 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 in AuthenticationController.cs
  • User Info Endpoint: /oauth2/identity - Returns user profile data
  • Client Management: /developer/app* - OAuth application registration and management

Authorization Flow:

  1. GET /oauth2/authorize: Renders consent screen and validates user authentication
  2. POST /oauth2/authorize: Processes user consent and creates authorization code via SignIn()
  3. 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:

  1. Consent UI: Posts to BL_API_URL + 'oauth2/authorize' with user approval
  2. Client Info: Fetches app details from BL_API_URL + 'oauthclient/info'
  3. 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

  1. Client redirects user to /oauth2/authorize with client_id, scope, response_type=code
  2. BeatLeader validates user authentication and renders consent screen
  3. User approves → authorization code generated via OpenIddict
  4. Client exchanges code for tokens at /oauth2/token (handled by OpenIddict)
  5. 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 ShowAllRatings is enabled.
  • Check connection: GET /api/beatleader/oauth/status shows connected, hasCreds, and hasSession.
  • Re‑login: use OAuth at /auth/beatleader/login or 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}/scores or /leaderboards/hash/{hash}, force session with ?auth=session and 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.