Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
---
title: Steam Session Ticket Authentication
---

SpacetimeAuth supports authentication using Steam's Session Ticket system. This allows
users to authenticate with your application using their Steam account.
This method is particularly useful for gaming applications that want to distribute
their applications on Steam.

Once a user authenticates with Steam, SpacetimeAuth will create an account for them
in your SpacetimeAuth project and issue an ID token that your application can use
to authenticate with SpacetimeDB. The ID token will contain claims with information
about the user and game ownership, which you can use for authorization in your application.

The ID token will notably contain the following claims:

- `sub`: The unique identifier for the user in SpacetimeAuth
- `provider_id`: The unique identifier for the user in Steam
- `login_method`: The authentication provider (in this case, "steam")
- `preferred_username`: The user's Steam display name
- `picture`: The URL to the user's Steam avatar (full size)
- `steam_owned_games`: An array of all the applications you published owned by the
user on Steam

## Creating a Steam Publisher Key

To use Steam Session Ticket authentication, you need to create a
[Steam Publisher Key](https://partner.steamgames.com/doc/webapi_overview/auth)
in the Steamworks dashboard. This key will be used to verify the authenticity of
the session tickets provided by Steam during the authentication process and to
retrieve information about the user's owned games.
To create a Steam Publisher Key, follow [Valve's official documentation](https://partner.steamgames.com/doc/webapi_overview/auth#create_publisher_key)

## Adding your Steam Publisher Key and allowed app IDs to SpacetimeAuth

Once you have your Steam Publisher Key, you need to add it to your SpacetimeAuth
project along with the list of allowed app IDs that you want to check for ownership.
You can do this in the SpacetimeAuth dashboard under the "Settings" section.

// TODO: Screenshot

Any app IDs that will authenticate users through Steam Session Tickets must be added
to the allowed app IDs list in SpacetimeAuth. This ensures that only session tickets
issued for those specific app IDs will be accepted during authentication. This is
an important security measure to prevent unauthorized access using session tickets
from other applications. Make sure to add all the app IDs for the games or DLCs you
want to check ownership for in your application.

## Getting a Steam Session Ticket

Now that you've set up your Steam Publisher Key and allowed app IDs, you can implement
the client-side logic to get a Steam Session Ticket and authenticate with SpacetimeAuth.
You can use the Steamworks SDK to retrieve a session ticket for the user and then
send it to your backend server for authentication.

Depending on the platform you're developing for, the process of obtaining a Steam
Session Ticket may vary.

Here are some resources to help you get started with retrieving a Steam Session Ticket:

- [Steamworks SDK documentation (C++/Unreal Engine)](https://partner.steamgames.com/doc/api/ISteamUser#GetAuthTicketForWebApi)
- [Steamworks .Net (C#/Unity)](https://steamworks.github.io/gettingstarted/)
- [GodotSteam (Godot Engine)](https://godotsteam.com/classes/user/#getauthticketforwebapi)
- [Steamworks.js (JavaScript/Node.js)](https://github.com/ceifa/steamworks.js)

:::warning
Make sure to request a session ticket with `spacetimeauth` as the identity parameter.
:::

## Exchanging the Steam Session Ticket for a SpacetimeAuth ID Token

Once you have the Steam Session Ticket, you can send it to the token endpoint of
SpacetimeAuth to exchange it for an ID token that you can use to authenticate with
SpacetimeDB.

Here is an example of how to exchange the Steam Session Ticket using `curl`:

```bash
curl -X POST https://auth.spacetimedb.com/oidc/token \
-H "content-type: application/x-www-form-urlencoded" \
-d "client_id=client_032xAh3p8o3zGzDghXsO5x" \
-d "grant_type=urn:spacetimeauth:steam-ticket" \
-d "steam_ticket=<YOUR STEAM TICKET>" \
-d "steam_app_id=<APP ID FROM WHICH YOU REQUESTED THE TICKET>"
```

## Checking App or DLC Ownership

You can check if a user owns a specific app or DLC by inspecting the `steam_owned_games`
claim in the ID token. This claim contains an array of all the applications you published
that the user owns on Steam. Each entry in the array includes the `appid` and a boolean
`ownsapp` indicating whether the user owns the app or not. You can use this information
to implement authorization logic in your application, such as granting access to
certain features or content based on game ownership.

```rust
#[derive(serde::Deserialize)]
struct SteamGame {
appid: u64,
ownsapp: bool,
}

#[derive(serde::Deserialize)]
struct CustomClaims {
steam_owned_games: Vec<SteamGame>,
}

#[reducer(client_connected)]
pub fn connect(ctx: &ReducerContext) -> Result<(), String> {
let jwt = ctx.sender_auth().jwt().ok_or("JWT required")?;
let claims: CustomClaims = serde_json::from_slice(jwt.raw_payload().as_bytes())
.map_err(|e| format!("Invalid JWT: {}", e))?;

const APP_ID: u64 = 2717550;
let owns = claims.steam_owned_games.iter().any(|g| g.appid == APP_ID && g.ownsapp);

if !owns {
return Err(format!("Unauthorized: does not own app {}", APP_ID));
}
Ok(())
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ authorize users with the SpacetimeDB server.
### Authentication methods

- Magic link
- Steam (Session Ticket)
- Github
- Google
- Discord
Expand Down
Loading