Client Authentication

Client authentication allows your backend server application to control client access to your channels.

Description

Web applications can grant their users access to Beebotte through a javascript library. Beebotte provides an authentication mechanism to restrict this access based on the Web application needs and policy. This authentication involves 3 parties:

  • The Web application user (through the web browser)
  • The Web application server
  • The Beebotte platform

This authentication mecanism applies for:

  • Subscribing to private resources
  • Subscribing to presence events
  • Writing and publishing to resources (public or private)

The only case where client authentication is not required is for reading from public channels.

The authentication workflows is described in the following points:

  1. The client creates a new instance of BBT. At this point, a websocket with a unique socket id is created between the client and Beebotte
  2. The client subscribes to a public resource: In this case, the subscription request is directly sent to Beebotte as subscribing to public resources does not require authentication
  3. The client subscribes to a private resource or to resource presence events:
    1. The client sends an authentication request to the Web APP's authentication end point providing the resource details and the permission to be granted (read access)
    2. The Web APP grants (or not) the permission by sending back the request signed using the secret key
    3. The client sends a subscription request to Beebotte providing the resource details and the authentication signature
    4. Beebotte checks the validity of the request and updates the permissions associated with the client socket id accordingly
  4. The client wants write access (to write or publish messages to a resource) to a resource:
    1. The client sends an authentication request to the Web APP's authentication end point providing the resource details and the permission to be granted (write access)
    2. The Web APP grants (or not) the permission by sending back the request signed using the secret key
    3. The client sends a grant request to Beebotte providing the resource details and the authentication signature
    4. Beebotte checks the validity of the request and updates the permissions associated with the client socket id accordingly

Client authentication options

The authentication procedure is completely transparent for the client. It is automatically triggered by the subscription requests (as described above).

When you initialise Beebotte client side API, you can specify your authentication endpoint and method (GET, POST).

/*
 * The authentication endpoint and method tells Beebotte client library where to authenticate
 * client subscriptions to specific resources.
 */
var bbt = new BBT('YOUR_API_KEY', {auth_endpoint: 'authentication_URL', auth_method: 'GET', userinfo: {token: 'my_token', username: 'rambo'}});

/* Subscribing to private resource will automatically request read access permission */
bbt.subscribe({
  channel: 'private-dev', //Note the 'private-' prefix
  resource: 'res',
}, function(err, msg){
  /* Do something here */
  /* Will get here every time a new resource data is written or published */
});

When initializing the client Javascript library, you can set the auth_endpoint and auth_method options to specify where and how the client will be authenticated.

  • auth_endpoint: is a URL endpoint on your backend that implements the authentication procedure
  • auth_method: the HTTP method, can be one of GET or POST

Implement authentication endpoint

The authentication endpoint should provide the authenticating client a signature to grant the requested access to Beebotte. The signature has the following form:

{"auth":"ApiKey:Signature"}

Signature = Base64( HMAC-SHA1( SecretKey, UTF-8-Encoding-Of( StringToSign ) ) );

StringToSign = sid + ":" + channel + "." + resource
   + ":ttl=" + ttl + ":read=" + read + ":write=" + write

With:
   sid: is the identifier of the websockets session subject to authentication between the client and Beebotte
   channel: the channel name the client is requesting access to
   resource: the resource name the client is requesting access to
   ttl: is the time in seconds the clients will be granted access to Beebotte
   read: boolean indicating if read access is requested
   write: boolean indicating if write access (write OR publish) is requested

In the following we provide a simple implementation of authentication endpoint for reference:

var express = require( 'express' );
var bbt = require('beebotte');
var bclient = new bbt.Connector({
  apiKey: 'YOUR_API_KEY',
  secretKey: 'YOUR_SECRET_KEY',
});

//Some express configuration omitted here

app.get( '/auth', function( req, res, next) {
  var device = req.query.channel,
  resource = req.query.resource || '*',
  ttl = req.query.ttl || 0,
  read = req.query.read || false,
  write = req.query.write || false,
  sid = req.query.sid,
  userinfo = req.query.userinfo;
  if( !sid || !channel ) return res.status(403).send('Unauthorized');

  /* Do something with userinfo
   * Userinfo gives the client a simple way to personalize the authentication of his users.
   */
  if(!userinfo || userinfo.token != 'my_token') return res.status(403).send('Unauthorized');

  var to_sign = sid + ':' + channel + '.' + resource +
      ':ttl=' + ttl + ':read=' + read + ':write=' + write;

  //utility function provided by Beebotte server library
  var auth = bclient.sign( to_sign );
  return res.send( auth );
} );
<?php
  require 'beebotte.php';
  $bbt = new Beebotte('YOUR_API_KEY', 'YOUR_SECRET_KEY');

  //Assuming GET method
  $sid      = $_GET["sid"];
  $channel  = $_GET["channel"];
  $resource = isset($_GET['resource']) ? $_GET['resource'] : '*';
  $ttl      = isset($_GET['ttl']) ? $_GET['ttl'] : 0;
  $read     = isset($_GET['read']) ? $_GET['read'] : "false";
  $write    = isset($_GET['write']) ? $_GET['write'] : "false";
  $userinfo = isset($_GET['userinfo']) ? $_GET['userinfo'] : null;

  if( !$sid || !$channel ) {
    header("HTTP/1.0 403 Unauthorized");
    echo 'Unauthorized';
  }

  /* Do something with userinfo
   * Userinfo gives the client a simple way to personalize the authentication of his users.
   */
  if( !$userinfo || $userinfo['token'] != 'my_token' ) {
    header("HTTP/1.0 403 Unauthorized");
    echo 'Unauthorized';
  }

  $tosign = $sid . ":" . $channel . "." . $resource . ":ttl=" . $ttl .
      ":read=" . ($read === "true") . ":write=" . ($write === "true");
  header('Content-Type: application/json; charset=utf-8');
  echo $bbt->sign($tosign);
?>