A Note on Browsers

Webex is fully browser compatible but we don’t distribute a browserified bundle at this time; you’ll need to build the bundle yourself. We use Browserify internally and webpack should work as well. We recommend using browserify or webpack for your project. If you prefer to load webex via a script tag, please follow the instructions in the README

OAuth

Since you don’t want to compile your access token into your app for everyone to use, you’ll need to ask users to enter a username and password (don’t worry, we’ve taken care of the hard parts for you).

Before you can login users with OAuth, you’ll need to register a new application on the Cisco Webex for Developers portal.

Implict Grant flow

The implicit flow is well suited for single page apps.

First, initialize the SDK with the URL you got from the portal:

var Webex = require('webex');
var webex = Webex.init({
  config: {
    credentials: {
      authorizationString: <your URL from the portal>
    }
  }
});

Then, initiate the login flow:

webex.authorization.initiateLogin()

After the user enters their user name and password and the page reloads, the SDK will take care of reading (and removing) the access token from the URL. Since this takes a few ticks, you’ll want to wait for the ready event, so change the previous block to something like the following.

webex.once(`ready`, function() {
  if (webex.canAuthorize) {
    // your app logic goes here
  }
  else {
    webex.authorization.initiateLogin()
  }
});

Authorization Code Grant Flow

The SDK’s behavior for the Authorization Code Grant flow is actually very similar to the Implicit flow, except for the fact that you need a backend server at play.

var Webex = require('webex');
var webex = Webex.init({
  config: {
    credentials: {
      authorizationString: <your URL from the portal>,
      clientType: 'confidential'
    }
  }
});

webex.once(`ready`, function() {
  if (webex.canAuthorize) {
    // your app logic goes here
  }
  else {
    webex.authorization.initiateLogin()
  }
});

By setting webex.config.credentials.clientType to confidential, initiateLogin will know to ask for an auth code instead of an access token.

The important difference is that when the login page redirects back to your app, you have a backend server that receives the redirect, exchanges the access code for a token, then redirects to your frontend. That might look something like the following:

app.get(`/oauth/redirect`, function(req, res) {
  assert(req.params.code);
  var webex = Webex.init({
    config: {
      credentials: {
        authorizationString: <your URL from the portal>,
        clientType: 'confidential'
      }
    }
  });
  webex.requestAuthorizationCodeGrant(req.params)
    .then(() => {

      res.redirect('/#' + querystring.stringify(webex.credentials.supertoken.toJSON())).end();
    });
});

Token Refresh

Since the frontend doesn’t have access to the client secret (and the implicit grant doesn’t support refresh tokens), you’ll need to write some custom code for doing token refresh.

The SDK accepts a refreshCallback for specifying your own refresh logic. The refreshCallback will be invoked with the webex instance and the current token object

Authorization Code Grant

The refreshCallback for this flow is pretty straightforward; just make a request to an endpoint on your backend that can proxy through to our refresh endpoint:

var Webex = require('webex');
var webex = Webex.init({
  config: {
    credentials: {
      authorizationString: <your URL from the portal>,
      clientType: 'confidential',
      refreshCallback: function(webex, token) {
        return fetch(`/oauth/refresh`, {
          method: `POST`,
          body: JSON.stringify({
            refresh_token: token.refresh_token
          })
        })
          .then((res) => res.json())
      }
    }
  }
});

And your backend might look something like

app.get(`/oauth/refresh`, function(req, res) {
  assert(req.params.refresh_token);
  var webex = Webex.init({
    credentials: {
      refresh_token: req.params.refresh_token
    },
    config: {
      credentials: {
        authorizationString: <your URL from the portal>,
        client_secret: <your client secret from the portal>
      }
    }
  });

  webex.refresh()
    .then(() => {
      res
        .send(webex.credentials.supertoken)
        .end();
    })
});

Implicit Grant

Technically, the implicit grant doesn’t allow token refresh. In particular, it doesn’t provide a refresh token. That said, a naive implementation of the refreshCallback could just ask users to login again:

var Webex = require('webex');
var webex = Webex.init({
  config: {
    credentials: {
      authorizationString: <your URL from the portal>,
      clientType: 'confidential',
      refreshCallback: function(webex, token) {
        webex.authorization.initiateLogin();
      }
    }
  }
});

But, if you don’t want to restart your user’s session, you could do something fancy (but beyond the scope of this document) where you might have the refreshCallback open a new tab, do an oauth flow, then return the token to the original tab. As long as the refreshCallback resolves with a plain object containing an access_token, just about any implementation should work.