Authentication

  1. What is authentication?
  2. How to authenticate
  3. What do I do after authentication?
    1. Store the session key
    2. Make authenticated requests to the hub server
    3. PostMessage the initial user balances

View our React template’s authentication code for a complete example of what all these steps look like in practice together.

When a player visits your experience page on the casino (e.g. /play/dan/pachinko), the casino loads your experience iframe url.

Your experience frontend then needs to authenticate them.

What is authentication?

This means sending a request to the hub server which will do two things:

  1. Reveal the user ID and username of the player on the casino
  2. Create a session for the player on the hub server so that the player can make authenticated requests to the hub server (e.g. to make bets)

How to authenticate

Your experience frontend authenticates the player by sending a hubAuthenticate GraphQL request to the hub server.

mutation Authenticate {
  hubAuthenticate(
    input: { casinoBaseUrl: "https://moneypot.com", userToken: "..." }
  ) {
    success {
      experienceId
      sessionKey
      uname
      userId
    }
    query {
      hubCurrentUser {
        hubBalancesByUserId {
          nodes {
            amount
            currencyKey
            hubCurrencyByCurrencyKeyAndCasinoId {
              displayUnitName
              displayUnitScale
            }
          }
        }
      }
    }
  }
}

Remember that you can add any additional GraphQL queries to the request so that you can authenticate and load any necessary initialization data in a single request.

As you can see in the query, you need to pass two things to the hub server:

  1. userToken: The userToken that the casino passed in the iframe url
  2. casinoBaseUrl: The base URL of the page iframing your experience (i.e. strip any path and params from the url)

Since the casino passes the userToken in the iframe url:

<iframe src="https://my-game.example.com#userToken={userToken}"></iframe>

Here’s how you can parse it:

const userToken = new URLSearchParams(window.location.hash.slice(1)).get(
  "userToken"
);

And here’s how you can get the parent window URL in a cross-browser way:

Show TypeScript code
// Try getting parent window URL from different sources in order of preference
function getCasinoBaseUrl(): string | null {
  const possibleUrls = [
    // Check ancestor origins, not available in every browser
    document.location.ancestorOrigins?.[
      document.location.ancestorOrigins.length - 1
    ],

    // Check referrer if it's different from current origin
    document.referrer !== window.location.origin ? document.referrer : null,
  ];

  const validUrl = possibleUrls.find((url) => url && URL.canParse(url));
  return validUrl ? new URL(validUrl).origin : null;
}

Why not just hard-code casinoBaseUrl = "https://moneypot.com"?

You could, but:

  1. It’s better practice to check who is iframing your experience
  2. In the future, dynamically determining the casino base URL sets the stage for supporting other MoneyPot casinos

What do I do after authentication?

Store the session key

Once you have the player’s sessionKey, you should store it so that you can make authenticated requests to the hub server.

Just store the sessionKey in memory instead of in localStorage.

The player will get a new session key any time they refresh the experience page which makes it less likely that the session key will expire or be hijacked by someone else using their browser.

Make authenticated requests to the hub server

You make authenticated requests by sending the session key in the Authorization request header:

fetch("https://hub.example.com/graphql", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `session:${sessionKey}`,
  },
  body: JSON.stringify({
    query: '...',
    variables: { ... }
   }),
});

Note: in practice you would use a library like graphql-request to make GraphQL requests to the hub server.

import { GraphQLClient, gql } from "graphql-request";

const client = new GraphQLClient("https://hub.example.com/graphql", {
  headers: {
    Authorization: `session:${sessionKey}`,
  },
});

const data = await client.request(query, variables);

Our React template shows how you can set up graphql codegen and TanStack Query to work with a graphql API in a pleasant, type-safe way.

PostMessage the initial user balances

More info: PostMessage API

Once the player is authenticated (and any time the player’s balance changes), the experience is required to post the player’s balances to the casino.

parent.postMessage(
  {
    type: "playerBalances",
    balances: {
      HOUSE: 100,
      BTC: 123,
    },
  },
  "*"
);