JSON Web Tokens (JWT)

Most Apps will want users to authenticate using their unique Covisint user credentials. This can be done via cui.js, which will invoke an API that in turn calls out to the given Applications Authentication Server for authentication.

The authenticated session is established and maintained via a combination of 1) a browser cookie that contains an Covisint encrypted JWT token and 2) an XSRF header value.

(The authentication payload also includes a second browser cookie that contains a Covisint ClearTrust token, thus permitting authenticated access to additional Covisint Application endpoints.)

Using cui.js, there are just two simple steps to getting this user-based authentication working in your App.

1. Defining an Auth Handler

An Auth Handler is just a function that wraps the JWT authentication call logic. It seems like nothing, but having an Auth Handler allows the App to remain oblivious to tracking authentication. Cui.js will track authentication state and automatically invoke the registered Auth Handler as necessary.

How does this work? After creating the initial cui.js object, an App will register an Auth Handler. Thereafter, the App need only make API data calls.

Whenever an authentication token does not exist or expires, the call will fail with a 401 (Unauthorized) Error Code. Cui.js will catch the 401 and rather than returning the error, will execute the authentication logic inside the Auth Handler.

An added benefit of this approach is that cui.js keeps track of the call that triggered the 401, and will re-issue that call automatically, once the subsequent authentication process is successful. For example,

// Note... place this code inside the cui.api(options).then() handler.

// Register the Auth Handler...
myCuiJs.setAuthHandler(function () {
  return myCuiJs.covAuth({
    originUri: 'your Covisint Application's originUri'
  })
  .then(function (response) {
    // ...do something now that user is authenticated
  })
  .fail(function (err) {
    // ...handle authentication error
  });     
});

The Auth Handler function must return a Promise. This makes it possible for cui.js to know when authentication succeeds, so it can then automatically re-issue the previous call.

⭐ If no Auth Handler is registered then every 401 is returned to the fail handler of the originating call.

2. Catching the Authentication response

The covAuth() call inside the Auth Handler calls out to the Covisint Application’s Authentication Server. Then, given successful authentication, the Authentication Server redirects back to your App, with a token parameter added onto the URL.

Cui.js must detect the receipt of this token so it can be cached. This is accomplished by placing the following call on the App page that is designated as the redirect for the Authentication Server. By default, this is the same page that executes the Auth Handler call (but can be App-specific, see below).

// Catch the authentication response
myCuiJs.handleCovAuthResponse();

That is it. 1) Define an Auth Handler and 2) catch the authentication response, and your cui.js App is enabled for JWT authentication. There is also flexibility built into this process, particularly relevant to Single Page Apps, which is detailed below.

⭐ A reference of all covAuth() and handleCovAuthResponse() options is available here.

3. Flexibility

The originUri property

The originUri uniquely identifies your Application inside the Covisint Platform (and is obtained when the Application is initially created).

During authentication, cui.js uses this value to retrieve additional Covisint Application endpoint URLs (which were automatically generated when your Application was created). This includes URLs for login and logout calls.

By default, cui.js will use the hostname of the App as the originUri, thus making passing this property superfluous. This is convenient and appropriate for most production Apps, which run from a URL that matches their originUri.

However, during development the hostname is often localhost. In such scenarios, it is necessary to explicitly specify a proper Covisint Application originUri in order to use JWT-based authentication. This is illustrated in the code example above.

Redirection

By default, after authentication cui.js will be redirected back to the App page that initiated the covAuth() call. This is important to know because that page MUST contain the handleCovAuthResponse() call that catches the returned authentication token (see above).

Now, considering that any 401 from any API will cause the App to fire the Auth handler, it stands to reason that this can potentially occur from any page in the App. Therefore, every page will need to contain the handleCovAuthResponse() call. In a classic server-based multi-page App this is straight-forward to accomplish-- just place the call in script that is included on every page.

However, in a Single Page App, although it is trivial to place handler code on every page, redirection presents considerable challenges. Because routing is often a framework-specific operation, cui.js cannot reliably return the user to the original route inside the App. In such a scenario, customization is necessary.

Here is an example from an AngularJS App that uses customization properties to properly handle post-authentication redirection.

// An AngularJS Auth scenario

// 1. Auth Handler...
myCuiJs.setAuthHandler(function () {
  return myCuiJs.covAuth({
    originUri: 'YOUR-COVISINT-APP-ORIGIN-URI',
    authRedirect: $location.absUrl(),
    appRedirect: $location.url(),
  })
  .then(function (response) {
    // ...do something now that user is authenticated
  })
  .fail(function (err) {
    // ...handle authentication error
  });     
});

// 2. Catching the returned token...
myCuiJs.handleCovAuthResponse({
  selfRedirect: true
  })
  .then(function(response) {
    // ...and do self-redirect back to where we were...
    $location.url(response.appRedirect).replace();
    return;
  });

Note, the covAuth() call redirects back to the base route of the App via the value specified for the authRedirect property. The appRedirect property, on the other hand, is set to the full URL that was active when the call originated.

Then, inside handleCovAuthResponse(), the selfRedirect property is set to true. This tells cui.js not to apply the value of appRedirect, but rather, to supply the value in the response, so the App can get it, and use its own framework-specific routing mechanisms to properly return the user to the original route.

The Auth Give Up Handler

An Auth Give Up Handler is a function that wraps App-specific routing logic. Having an Auth Give Up Handler allows the App to safeguard against upstream authentication failure scenarios that might result in the App infinitely looping.

Cui.js tracks authentication attempts, and will terminate its built-in retry feature after 2 consecutive failures. It will then invoke any registered Auth Give Up Handler. This allows the App to gracefully and/or forcefully terminate the App’s attempt to call the authentication services. This is particularly useful in Apps with sophisticated routing logic, that otherwise might continue attempting to authenticate.

Here is an example for an Angular-based App.

// Note... place this code inside the cui.api(options).then() handler.

// Register the Auth Give Up Handler...
myCuiJs.setAuthGiveUpHandler(function () {
  // Force the App to use a route that does NOT require authentication...
  $state.go('misc.notAuth');
  // ...and optionally displays a meaningful message describing the situation.
        
  // NB must return REJECTED promise!
  return $.Deferred().reject();
});

The Auth Give Up Handler function must return a REJECTED Promise. This makes it possible for cui.js to know when authentication fails, so it can then properly return control to the App.