Auth Scenarios¶
To avoid confusion, we have 3 different scenarios where authentication is needed
Scenario 1: Operator to Gamnify¶
Auth Type: Shared Key
Products: Instant Feed, Scheduled Feed
Used specifically whenever the operator needs to call a Gamnify API and Gamnify needs to make sure the caller is the operator. This example is used for feed import calls, or for initiation of server-to-server instant feed generation. In this scenario, we will be using a shared key to hash the call and verify.
Scenario 2: Gamnify to Operator¶
Auth Type: Shared Key
Products: Games (PAM API)
Gamnify needs to call the operator and the operator needs to ensure the caller is indeed Gamnify. For example, this is needed when Gamnify calls the operator wallet to credit or debit money. In this scenario, we will be using a shared key to hash the call and verify.
Scenario 3: Player to Gamnify¶
Auth Type: Operator Token
Products: Games
This is a different scenario in which an operator-generated token is sent by the player to Gamnify, and Gamnify will just pass through this token over to the operator. This scenario is used in conjunction with point 2 whenever we're using the betting api and we need to credit or debit funds.
Shared Key & Hash Integration¶
Gamnify will supply the operator with 2 shared keys. We use two rather than one key simply to be able to change and rotate keys without any downtimes. It is the responsibility of the operator to make sure that the hash verification is done against both the primary and secondary keys.
sequenceDiagram
participant Initiator
participant Server
Initiator->>Initiator: Create Request
Initiator->>Initiator: Create Hash
Initiator->>+Server: Send Request with Hash
Server->>Server: Verify Hash
Server->>Server: Process Request
Server->>-Initiator: Send Response
In the above sequence diagram, the initiator is the party that is creating the request. e.g.: - In case the operator is importing a feed, the operator is the initiator, whilst Gamnify's feed exporter service is the server. - In case of a wallet integration, Gamnify's betting engine will be the initiator whilst the operator's wallet api will be the server.
Whenever the initiator creates an HTTP request, an X-AUTH-HASH header should be created by concatenating the key, the relative url, and the body of the request, and then using a SHA256 hash.
The following is an example of a hash generator for C# / dotnet core.
public static string GenerateHashForRequest(string requestUrl, string? requestBody, string authKey)
{
// Trim any trailing slashes
requestUrl = requestUrl.TrimEnd('/');
// Concatenate the auth key, request url and body (if any)
string input = $"{authKey}{requestUrl}{requestBody ?? ""}";
// Generate the sha256 hash
return GenerateHash(input);
}
public static string GenerateHash(string input)
{
var hashedBytes = System.Security.Cryptography.SHA256.HashData(Encoding.UTF8.GetBytes(input));
return BitConverter.ToString(hashedBytes).Replace("-", "").ToLower();
}
The server should re-verify this hash to make sure that the caller is indeed known. The following is an example of the logic needed to verify the hash on the server side.
public static bool VerifyHashForRequest(string getRequestUrl, string? requestBody, string primaryKey, string secondaryKey, string hash)
{
return
GenerateHashForRequest(getRequestUrl, requestBody, primaryKey) == hash ||
GenerateHashForRequest(getRequestUrl, requestBody, secondaryKey) == hash;
}
Please note that whilst it is not mandatory, we recommend that for any get calls whose url doesn't change, you should add an additional fake parameter with a timestamp. This forces a different hash to be produced by the initiator, which in turn forces the server to revalidate the hash everytime. For example:
Not Recommended
https://feed-export-api-gt-test.gamnify.tech/v1/scheduled/sports/competitions
Recommended
https://feed-export-api-gt-test.gamnify.tech/v1/scheduled/sports/competitions?timestamp=20240101235959
The hash will be sent in the below requests by Gamnify:
POST /integration/wallet/transactionGET /integration/wallet/transactionGET /integration/identity/player
And will be passed under the X-AUTH-REQUEST-HASH header. It is up to the operator to verify the recieved has as explained above.
Player Authentication¶
In the scenarios where knowledge of the player is needed (for example, if the operator is using Gamnify's Betting API), then we need to make sure that the player is properly authenticated. This doesn't apply to feed integrations.
To simplify the integration and avoid round trips, Gamnify will just pass through tokens and puts the responsibility of authenticating the token on the operator's side.
For a full workflow, please refer to the /player-api/bet-flow.md page The following is a typical workflow whereby authentication is needed:
Please note that if the operator allows for multiple active sessions for a single user, then Gamnify will also allow for multiple active sessions. This is by design, and the responsibility is on the operator side should the operator decide to have a single active session instead.