Access Tokens

Generating an access token should be done in the backend, as this is the only place you can securely protect from your users. If you want to generate the access token in your client application you can skip this step and proceed with Sending Events.

If you already have a backend (i.e. HTTP server or Cloud Functions like Lambda or Google Cloud Functions) it’s easy to create such a backend webservice. If you don’t have any backend for your game, we suggest using Google Firebase which is very cheap and Cloud Functions can be easily created using JavaScript (NodeJS) or PHP.

Please note

The example code provided in this guide already contains our public demo API-Key that you can use to get started. The SCILL team has preconfigured some basic challenges that are used in this guide to get you started quickly. At any time you can sign up for free to create your own products, API keys and customize your challenges.

NodeJS

If your backend runs on NodeJS you can integrate sending events like this:

Step 1: Install JavaScript SDK

npm install @scillgame/scill-js --save

You will now have installed our NPM module and can use it in your NodeJS based code. Please upgrade the package regulary to get updates and bug fixes.

Step 2: Initialize module

Add this to the head of your NodeJS code or cloud function.

Importing SCILL class
const scill = require('@scillgame/scill-js');

Congratulations! You have configured a SCILL class that can be used to send events and generate access tokens. Refer to the API-Reference to learn what you can do with it.

Step 3: Getting access token

Please note

This step is only required if your user facing code is running in an unsecure client environment like a game, an iOS or Android app or a JavaScript based client web application (SPA with Angular, React, Vue, …). If your web site is created on the server side - i.e. with PHP you don’t need to create an access token. In this case, just use your API key (or the API key provided in this example).

You don’t want to expose User IDs and/or the API-key in unsecure environments as this would allow anyone with some basic knowledge of the browsers web console to extract those and being able to send requests without your permission. To secure this, you create an access token for each user for each client session.

In your NodeJS backend you need to provide a webservice that your client can call to get an access token. You will most likely already have some sort of webservice so this is just a very basic example code based on a simple express server.

NodeJS server example
// This example implements a NodeJS backend receiving sessions from your client and asking SCILL
// to generate an access token for the userId "encoded" in/via the session.

const express = require('express');
const bodyParser = require('body-parser');
const scill = require('scill');

// Generate an instance of the SCILL SDK with example API-Key
const auth = scill.getAuthApi('ai728S-1aSdgb9GP#R]Po[P!1Z(HSSTpdULDMUAlYX');

const app = express();
const port = 80;

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.get('/scill/generate-access-token', (req, res) => {
    // In this example we use a session sent to this endpoint from the client to extract a user id from the session
    // How you implement that is up to you and depends on your user system
    const session = req.body.session;
    const userId = '1234';

    // Call SCILL backend to generate an access token encoding user and API-Key
    return auth.generateAccessToken({
        userId: userId
    }).then(accessToken => {
        // return access token
        return res.send(accessToken);
    });
});

app.listen(port, () => {
    console.log('Example app listening at http://localhost:${port}');
});

The SCILL JavaScript SDK function generateAccessToken is used to generate an access token based on the user id you are providing. What happens here is that SCILL receives your API-Key together with the user id and then creates as well as signs a JWT token.

More info on this topic can be found in the Authentication document.

Please note: A cheater/hacker only needs to get his hands on userid and your api key to send events “on your behalf”. Everything else is public information and can be found in this documentation (i.e. SCILL endpoints to send events to).

Whatever your implementation looks like, make sure that you follow these basic rules:

  • Don’t expose any part of the access token generation to the user, especially the api key and the userid
  • Don’t think that any sort of client side “obfuscation” does help in any way - hackers overcome these things in minutes
  • Your design must be secure by design. If you follow this guide it definitely will be.
  • All communication must be done via HTTPS

PHP

If your backend runs on PHP you can integrate sending events like this:

Step 1: Install PHP SDK

composer require scill-php

If you don’t use composer in your project you can also download the PHP SDK from Github and import the classes manually into your project.

Step 2: Initialize library

Use autoload.php to initialize PHP library and setup an instance of the SCILLClient class by providing your API key.

Getting SCILL Client instance
<?php
    require_once(__DIR__ . '/vendor/autoload.php');

    // Setup SCILL Events client instance
    $scillClient = new \SCILL\SCILLClient('ai728S-1aSdgb9GP#R]Po[P!1Z(HSSTpdULDMUAlYX');
    $scillEvents = $scillClient->getEventsClient();
?>

Congratulations! You have set up an instance of the SCILL SDK class, that can be used to send events and generate access tokens. Refer to the API-Reference to learn what you can do with it.

Step 3: Generate access token

You don’t want to expose User IDs and/or the API-key in unsecure environments as this would allow anyone with some basic knowledge of the browsers web console to extract those and being able to send requests without your permission. To secure this, you create an access token for each user for each client session.

This example is based on the Slim Framework to quickly create REST-APIs with PHP to get you an idea how to implement it.

Slim route to generate access token
<?php
    $app->get('/scill/generate-access-token', function (Request $request, Response $response) {

        // In this example we expect that the client sends us a session id that we decode to receive a user id
        // This could also be a JWT token or a Steam Session. Whatever it is, it's your job to receive an encoded
        // user auth from the client, to decode it into a user id
        $params = $request->getQueryParams();
        $userId = null;
        if (!$params || !$params["session"]) {
            $response->getBody()->write('No session provided');
            return $response;
        } else {
            // Decode the session - in this example we just hardcode it
            $userId = "1234";
        }

        // Create the request to generate an access token
        /** @var \SCILL\SCILLClient $scill */
        $scill = $this->get('scill');

        $payload = new \SCILL\Model\ForeignUserIdentifier();
        $payload->setUserId($userId);

        // Run the request and if everything worked fine we can return the access token to the client
        try {
            $result = $scill->getAuthClient()->generateAccessToken($payload);
            $accessToken = $result->getToken();
            $result = array(
                "success" => true,
                "token" => $accessToken
            );
            $response->getBody()->write(json_encode($result));
        } catch(\SCILL\ApiException $exception) {
            $result = array(
                "success" => false,
                "error" => $exception->getMessage()
            );
            $response->getBody()->write(json_encode($result));
        }
        return $response;
    });
?>

The function generateAccessToken is used to generate an access token based on the user id you are providing. What happens here is that SCILL receives your API-Key together with the user id and then creates as well as signs a JWT token.

More info on this topic can be found in the Authentication document.

Please note: A cheater/hacker only needs to get his hands on userid and your api key to send events “on your behalf”. Everything else is public information and can be found in this documentation (i.e. SCILL endpoints to send events to).

Whatever your implementation looks like, make sure that you follow these basic rules:

  • Don’t expose any part of the access token generation to the user, especially the api key and the userid
  • Don’t think that any sort of client side “obfuscation” does help in any way - hackers overcome these things in minutes
  • Your design must be secure by design. If you follow this guide it definitely will be.
  • All communication must be done via HTTPS

PlayFab

If your game uses PlayFab authentication, it’s very easy to connect to SCILL.

Step 1: Create CloudScript function

Just copy & paste this cloud function to your cloud script file or repository and use PlayFabClientAPI.ExecuteCloudScript API to execute the cloud function with the current PlayFab user id.

PlayFab Cloud Function
JavaScript
// This function generates a SCILL access token for the current PlayFab user.
// More info can be found here: https://developers.scillgame.com/api/authentication.html
handlers.generateSCILLAccessToken = function (args, context) {
   // Set your API Key created in the SCILL Admin Panel
   var scillApiKey = "ai728S-1aSdgb9GP#R]Po[P!1Z(HSSTpdULDMUAlYX";

   var headers = {
      "Authorization": "Bearer " + scillApiKey
   };

   // Provide the current playfab id as the user_id. Please make sure to use the
   // same user_id when sending events from the backend and use the generated
   // access token on client side
   var body = {
      user_id: currentPlayerId
   };

   // Prepare request to SCILL cloud
   var url = "https://us.scill.4players.io/api/v1/auth/access-token";
   var content = JSON.stringify(body);
   var httpMethod = "post";
   var contentType = "application/json";

   // The pre-defined http object makes synchronous HTTP requests to SCILL cloud
   var response = http.request(url, httpMethod, content, contentType, headers);
   var parsedData = JSON.parse(response);

   // Return the access token as a string
   return parsedData.token;
};

Step 2: Execute Cloud Script in Game

This function will return the token as a string or an error. In Unity, you can override the SCILLManager class to load the access token from the cloud function:

Execute PlayFab Cloud Function
C#
// The default SCILLManager implementation creates access token in client - which is not recommended for production
public class MySCILLManager : SCILLManager {
   // Override SCILLManager class with custom implementation
   public override IPromise<string> GenerateAccessToken(string userId)
       // Execute cloud script created earlier and either return access token or error
       PlayFabClientAPI.ExecuteCloudScript(new ExecuteCloudScriptRequest()
       {
           FunctionName = "generateSCILLAccessToken", // name of function created in PlayFab cloud
           GeneratePlayStreamEvent = true
       },
       (ExecuteCloudScriptResult result) =>
       {
            // Return the access token returned by the cloud function back to the SCILLManager to set up everything
            return Promise<string>.Resolved(result.FunctionResult);
       },
       (PlayFabError error) =>
       {
            return Promise<string>.Rejected(error.errorMessage);
       });
   }
}

Generate access token in game

If you skipped implementing a backend to generate the access token you can also generate the access token in your application. However, this exposes the API-Key in your application bundle which is not recommended as developers/hackers can decompile your binary and might be able to retrieve your API-key.

You can generate the access token with the AuthApi class:

Generating Access Code in Client
AuthApi authApi = _scillClient.getAuthApi("YOUR_API_KEY");
AccessToken response = authApi.GenerateAccessToken(foreignUser);
string accessToken = response.token;

foreignUser is the user id. The user id must stay the same as this connects data within SCILL to your user. However it’s best not to use an “auto increment” value from your database that allows hackers but it should be some sort of unique id.