Authentication
View SourceAsobi supports multiple authentication methods: username/password, OAuth/OIDC social login (Google, Apple, Microsoft, Discord), Steam, and device-based auth.
Players can link multiple providers to a single account.
Username & Password
The simplest method. Register and login to receive a session token:
curl -X POST http://localhost:8080/api/v1/auth/register \
-H 'Content-Type: application/json' \
-d '{"username": "player1", "password": "secret123"}'
{"player_id": "...", "session_token": "...", "username": "player1"}Use the session token in subsequent requests:
Authorization: Bearer <session_token>OAuth / Social Login
For game clients, Asobi uses server-side token validation. The game client authenticates with the platform SDK (Google Sign-In, Apple Sign-In, etc.) to obtain an ID token, then sends it to Asobi for validation.
POST /api/v1/auth/oauthFlow
- Player taps "Sign in with Google" in your game
- Platform SDK returns an ID token (JWT)
- Game client sends the token to Asobi
- Asobi validates the JWT against the provider's JWKS
- If the identity exists, the player is logged in
- If not, a new player account is created and linked
Example
curl -X POST http://localhost:8080/api/v1/auth/oauth \
-H 'Content-Type: application/json' \
-d '{"provider": "google", "token": "eyJhbGciOiJSUzI1NiIs..."}'
First-time response (new account created):
{
"player_id": "...",
"session_token": "...",
"username": "google_abc12345_4821",
"created": true
}Returning player response:
{
"player_id": "...",
"session_token": "...",
"username": "player1"
}Supported Providers
| Provider | provider value | Issuer |
|---|---|---|
"google" | https://accounts.google.com | |
| Apple | "apple" | https://appleid.apple.com |
| Microsoft | "microsoft" | https://login.microsoftonline.com/common/v2.0 |
| Discord | "discord" | https://discord.com |
| Steam | "steam" | N/A (custom, see below) |
Configuration
Add provider credentials to your sys.config:
{asobi, [
{oidc_providers, #{
google => #{
issuer => <<"https://accounts.google.com">>,
client_id => <<"YOUR_CLIENT_ID">>,
client_secret => <<"YOUR_CLIENT_SECRET">>
},
apple => #{
issuer => <<"https://appleid.apple.com">>,
client_id => <<"YOUR_CLIENT_ID">>,
client_secret => <<"YOUR_CLIENT_SECRET">>
}
}}
]}Each provider needs a client ID and secret from the respective developer console:
- Google: Google Cloud Console → APIs & Services → Credentials
- Apple: Apple Developer → Certificates, Identifiers & Profiles → Service IDs
- Microsoft: Azure Portal → App registrations
- Discord: Discord Developer Portal → OAuth2
Steam
Steam uses session tickets instead of OIDC. The game client obtains a ticket
via ISteamUser::GetAuthSessionTicket and sends the hex-encoded ticket.
curl -X POST http://localhost:8080/api/v1/auth/oauth \
-H 'Content-Type: application/json' \
-d '{"provider": "steam", "token": "14000000..."}'
Asobi validates the ticket via the Steam Web API and fetches the player's display name from their Steam profile.
Configuration
{asobi, [
{steam_api_key, <<"YOUR_STEAM_WEB_API_KEY">>},
{steam_app_id, <<"YOUR_STEAM_APP_ID">>}
]}Get your API key from the Steam Partner site.
Linking Providers
Players can link additional providers to their existing account. This allows them to sign in from different platforms (e.g., link both Google and Steam to the same player).
Link a Provider
Requires an authenticated session.
curl -X POST http://localhost:8080/api/v1/auth/link \
-H 'Authorization: Bearer <session_token>' \
-H 'Content-Type: application/json' \
-d '{"provider": "discord", "token": "eyJhbGciOi..."}'
{"provider": "discord", "provider_uid": "123456789", "linked": true}Unlink a Provider
Asobi prevents unlinking the last auth method to avoid locking the player out.
curl -X DELETE http://localhost:8080/api/v1/auth/unlink \
-H 'Authorization: Bearer <session_token>' \
-H 'Content-Type: application/json' \
-d '{"provider": "discord"}'
{"success": true}WebSocket Authentication
After obtaining a session token (from any auth method), connect to the WebSocket and authenticate:
{
"type": "session.connect",
"payload": {"token": "<session_token>"}
}The token works the same regardless of which provider was used to obtain it.
SDK Integration
Unity (C#)
// Google Sign-In → Asobi
string idToken = googleSignIn.IdToken;
var response = await asobi.Auth.OAuth("google", idToken);
// response.SessionToken is now set automaticallyGodot (GDScript)
# Google Sign-In → Asobi
var id_token = google_sign_in.get_id_token()
var result = await asobi.auth.oauth("google", id_token)
# Session token is stored internallyDart / Flutter / Flame
// Google Sign-In → Asobi
final idToken = googleSignIn.currentUser!.authentication.idToken!;
final result = await asobi.auth.oauth('google', idToken);
// Session token is stored internallyDefold (Lua)
-- Google Sign-In → Asobi
local id_token = google_sign_in.get_id_token()
asobi.auth.oauth("google", id_token, function(result)
-- Session token is stored internally
end)Next Steps
- In-App Purchases -- receipt validation for Apple and Google
- REST API -- full API reference
- WebSocket Protocol -- real-time message types