callstats.io

The callstats Developer Hub

Welcome to the callstats developer hub. You'll find comprehensive guides and documentation to help you start working with callstats as quickly as possible, as well as support if you get stuck. Let's jump right in!

Guides    API Reference

Other Authentication Mechanisms and API

Basic, Whitelisting (originURL), JWT authentication

Apart from Basic authentication that uses a clear text appSecret, we also allow whitelisting (i.e., only particular origin URLs can report stats), or a full blown third-party authentication based on JWT mechanics.

Basic Authentication over HTTPS

The application requires an AppID and AppSecret to authenticate with callstats.io. The origin server is expected to pass the userID for each endpoint in a WebRTC call. The callstats.js internally implements a 4-way handshake, based on simple challenge-response protocol. If successful, the callstats.js generates a token valid for 2 hours. The token is subsequently used by the callstats.js to send event and measurement data to callstats.io.

White-listing (Optional but highly recommended)

callstats.io uses the “Origin” header in the HTTP request to fetch the request’s origin. RFC6454 explains the algorithm used by user-agents to compute the “Origin” header.

callstats.io compares the Origin URL sent by the HTTP user-agent in the authentication message with the stored Origin URL for that particular AppID. If the origins match, callstats.io returns a new token and associates the token to the requesting userID. Alternatively, if the origins does not match, callstats.io rejects the request, and denies access to that particular user-agent.

3rd party authentication

Instead of relying only on the endpoint for authentication, the callstats.io also implements third-party authentication, which requires the origin server to generate token for the endpoint which is then used to authenticate the endpoint. 3rd party authentication is discussed in detail in a later section.

Token format used by callstats.io’s third party authentication system is JWT. Currently the only supported algorithm is ES256.

API

Authenticates with the callstats.io backend to setup a trusted relationship with it.

ParamsArgumentTypeDescription
AppIDRequiredStringApplication ID is obtained from callstats.io.
tokenGeneratorRequiredcallbackCallback to generate token.
localUserIDRequiredString (128 bytes) or Objectit is provided by the developer and MUST NOT be null or empty.
csInitCallbackOptionalcallbackasynchronously reports failure or success of the protocol messages.
csStatsCallbackOptionalcallbackasynchronously reports the conference statistics.
configParamsOptionalJSONit is the set of parameters to enable/disable certain features in the library.

Token Claims

Token supports following claims:

ClaimRequired/optionalTypeDescription
appIDRequiredStringThis is your AppID.
userIDRequiredStringThis is endpoint's local user identifier.
keyIDRequiredStringID of the key that was used to generate this token. This can be obtained from secrets configuration page
expOptionalNumericDate Token expiration time. It's recommended that this is set 5-10 minutes into the future.
nbf OptionalNumericDateToken not valid before. It's recommended that this is set 5-10 minutes into the past.
jti Optional StringJWT ID. This is used for audit logging.
{
  "userID":"4358",
  "appID":"545619706",
  "keyID":"0123456789abcedf00",
  "iat":1465221382,
  "nbf":1465221682,
  "exp":1465221682,
  "jti":"25b30fb33a7764d2971534507718f35274bb"
}

Alternative Step 2: Initialize() with JWT (Client example)

After the user is authenticated with the origin server (or when the page loads), call initialize() with appropriate parameters (see API section). Check the callback for errors. If the authentication succeeds, callstats.js will receive an appropriate authentication token to make subsequent API calls.

//initialize the app with application tokens
  var AppID     = "YOUR APPLICATION ID";

  function exampleTokenGenerator(initialToken) {
    var cached = null;
    if (initalToken)
     var cached = initialToken;
    // forcenew = set to true if application should generate new token and false if
    // it's okay to use cached token
    // callback(error, token). error should be set to non-null if there was an
    // non-recoverable error. Token should be the JWT. Please see section
    // "Third-party Authentication" for more complete documentation
    return function(forcenew, callback) {
      if (!forcenew && cached !== null)
        return callback(null, cached);
      // 1. get new token
      var xhr = new XMLHttpRequest();
      xhr.open('POST', '/getToken');
      xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
      xhr.onload = function() {
        // Did we get 200 OK response?
        if (xhr.status == 200) {
          // Get token and send it to callback
          var resp = JSON.parse(req.responseText);
          // the token should contain the claims defined in third party authentication
          return callback(null, resp.token);
        }
        console.log("Couldn't get the token");
        console.log(req.responseText);
        // if uncorrectable error happens, inform callstats.io
        return callback('Unknown error');
      };
      xhr.send(data);
    };
  }

  function csInitCallback (err, msg) {
    console.log("Initializing Status: err="+err+" msg="+msg);
  }

  //userID is generated or given by the origin server
  callstats.initialize(AppID, exampleTokenGenerator(initialToken), userID, csInitCallback, csStatsCallback, configParams);

Generating a JSON Web Token (JWT)

You can use the following code as an example to generate JWT for authenticating the endpoint.
To correctly generate a token keep in mind the following:

  1. Create a token header as a JSON:
{
  "typ":"JWT", 
  "alg":"HS256"
}
  1. Create a token payload as a JSON in the format:
{ 
  "userID": x, 
  "appID": a, 
  "keyID": k, 
  "iat": i, 
  "nbf": n, 
  "exp": e, 
  "jti": j 
}

Please note that iat , nbf, exp, jti are optional, but it is recommended to use it, otherwise the token won't be timed out. More information can be found in RFC 7519.

  1. Encode with base64 stringified header and payload and join them with dot.
    In pseudo code something like:


    token = base64Encode(JSON.stringify(header)) + "." + base64Encode(JSON.stringify(payload))

  2. Sign your token with HMAC SHA-256 algorithm

  3. Use signed token "code" in the message that you send in the authentication request

var express = require('express');
  var jwt = require('jsonwebtoken');
  var app = express();
  var fs = require('fs');

  var crypto = require('crypto');

  // Your ECDSA private key for which the public key is submitted to
  // callstats.io dashboard
  var key = fs.readFileSync('ecprivate.key');
  var keyid = '0102030405060709';
  var appid = 12345678;
  // Dummy audit log
  var audit = {log: console.log};

  // Dummy session middleware
  app.use(function (req, res, next) {
    req.user = {id: 300};
    next();
  });

  // Dummy JWT ID generator
  var randomIdGenerator = function () {
    return 42;
  };

  app.post('/getToken', function (req, res) {
    if (!req.user) {
      res.status(403);
      return res.send(JSON.stringify({error: "User not logged in"}));
    }
    var randomid = randomIdGenerator().toString();
    var token = null;
    try {
      token = jwt.sign(
        {
          userID: req.user.id.toString(),
          appID: appid,
          keyID: keyid
        }, key,
        {
          algorithm: "ES256",
          jwtid: randomid,
          expiresIn: 300, //5 minutes
          notBefore: -300 //-5 minutes
        });
    } catch (err) {
      console.log(err);
      res.status(500);
      return res.send(JSON.stringify({error: "Token creation failed"}));
    }
    audit.log({action: "GrantToken", user: req.user.id, tokenid: randomid});
    res.status(200);
    res.send(JSON.stringify({token: token}));
  });

  app.listen(3000, function () {
    console.log('Example app listening on port 3000!');
  });

Updated 2 years ago


Other Authentication Mechanisms and API


Basic, Whitelisting (originURL), JWT authentication

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.