Steamworks getAuthTicketForWebApi

Not favoritedFavorited Favorited 0 favourites
  • 13 posts
  • Heya!

    First off, thanks for the great work on the Steamworks plugin! Appreciate the latest update.

    I'm currently building a game that uses a custom backend server, and I've run into a security need. To safely validate that API requests are actually coming from an authenticated player, my server needs to verify an auth ticket from the client. The standard way to do this is by having the client generate a ticket using Steam's GetAuthTicketForWebApi function and sending it with each request.

    This function isn't currently exposed in the plugin's actions. It would be sweet if you could add a scripting function to get this ticket. An async function that fits the style of the current API would be perfect, something like:

    // Awaiting this promise would return the ticket string const ticket = await runtime.objects.Steamworks.getFirstInstance().getAuthTicketForWebApi();

  • It's not entirely clear to me how this all works - looking at GetTicketForWebApiResponse_t in the documentation, it looks like you get both a HAuthTicket (really a uint32) and m_rgubTicket which appears to be a block of binary data up to 2560 bytes long. Do you only need the HAuthTicket?

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • My server needs the m_rgubTicket data. I just send that ticket string to Steam's web API to verify the user.

    The HAuthTicket handle is just for the client to use, my server never sees it.

    So if the async function could just return the m_rgubTicket as a hex string, that'd be perfect.

  • I've implemented this for the next release of the Steamworks plugin. If you're feeling brave you can try the code already on the GitHub repo which supports Windows, but otherwise I will update the macOS/Linux builds next week and release the update.

  • Oh wow, I checked out the commit and it looks great! This is why I recommend Construct 3 to everyone—support is top notch and consistent (across decades). Thanks Ashley!

  • I just published an update to the Steamworks addon (v1.4.1) which includes the authentication ticket features. Let me know if it's all working for you.

  • Heya! Following up, the getAuthTicketForWebApi feature seems to be working great, and my server is correctly validating the tickets. Fantastic!

    But there's a slight problem. I've run into an edge case with Steam Family Sharing that I wanted to bring to your attention. When someone plays my game via Family Sharing, I've found that the auth ticket generated by the plugin correctly belongs to the player's account. However, the Steam.StaticAccountKey expression returns the Steam ID of the owner's account.

    This creates a mismatch that my backend server flags as an invalid request (as it should). It sees a valid ticket for Player A, but the request claims to be from Player B. My AI took a peek at the GitHub repo to understand it better, and noticed the user ID is retrieved from the UserStatsReceived_t callback. A potential fix might be to use the standard SDK function SteamUser()->GetSteamID() instead. This synchronous call should always return the ID of the actual current player, which would resolve the issue in Family Sharing scenarios.

    I could just use the ID from the validated ticket as a source of truth.. However I think it should be addressed at the root, as I have other logic in my client that utilizes Steam.StaticAccountKey.

  • My AI took a peek at the GitHub repo to understand it better, and noticed the user ID is retrieved from the UserStatsReceived_t callback.

    That's incorrect - the plugin actually ignores that event (typical AI hallucination...) It currently just logs to the console in that event and does nothing about it.

    A potential fix might be to use the standard SDK function SteamUser()->GetSteamID() instead. This synchronous call should always return the ID of the actual current player, which would resolve the issue in Family Sharing scenarios.

    This is what the plugin already does: it ends up calling SteamUser()->GetSteamID().GetStaticAccountKey().

    So I'm not sure what the problem would be - perhaps there's some other ID we need to expose with the plugin, but I don't know what that would be - it probably depends on how all the server-side validation works. It might be a good idea to ask Valve for support.

  • True, alrighty I think this is more informative: The ticket’s steamid is the authoritative player identity; exposing both GetSteamID() and GetAppOwner() on the client will make Family Sharing behavior explicit.

    So it seems my initial comment was not the complete picture. Using a single “StaticAccountKey” (derived from SteamUser()->GetSteamID().GetStaticAccountKey()) is not great due to this concept of borrower vs owner.

    The Web API AuthenticateUserTicket returns both identities: the actual player steamid and the ownersteamid. This means identity can differ in Family Sharing and that the ticket’s steamid is the authoritative player identity for auth.

    So maybe we can expose two explicit accessors alongside any existing “static account key”?:

    Borrower ID (64-bit): SteamUser()->GetSteamID().ConvertToUint64()

    Owner ID (64-bit): ISteamApps()->GetAppOwner().ConvertToUint64()

    Then it aligns client API with what the server must already handle (two IDs).

  • OK, I'll look in to exposing the app owner account details via the plugin.

  • Appreciate it!

  • I just published an update to the Steamworks addon (v1.4.2) which includes the new expressions AppOwnerAccountID and AppOwnerStaticAccountKey (based on the Steam ID of GetAppOwner()). Hopefully that now covers everything you need.

  • Works great! Thanks for adding it!

Jump to:
Active Users
There are 0 visitors browsing this topic (0 users and 0 guests)