Building Serverless Web Applications with OpenWhisk

Apache OpenWhisk is an open source cloud platform that executes functions in response to events at any scale. For example OpenWhisk can be used to run business logic in response to invocations from web and mobile apps over HTTP. This article describes how to build web applications where users can log in via their Google accounts and OpenWhisk is used to host protected APIs.

OpenWhisk on Bluemix comes with an API Gateway to manage access to APIs that have been implemented as OpenWhisk actions. For user authentication Google, Facebook and GitHub accounts can be used.

serverless-webapp

For serverless web applications the challenge is how to do the OAuth dance since you cannot put the client secret into the client side web application for security reasons. This functionality must be done in some code that runs on a server, for example a Node.js application. Since I wanted to avoid having to host a server side application, I wanted to use OpenWhisk instead. Fortunately I found sample code from my colleagues Nick Mitchell and Lionel Villard that came close to my requirements.

Please note that the term “serverless” might be confusing here. Serverless does not mean there is no server involved at any time, it means you don’t have to host and operate server-side code since this is taken care of by the “Functions as a Service” provider, in this case OpenWhisk.

I’ve open sourced a simple web application built with Angular 4 which sends a redirect to Google when users want to log in (see code).

onButtonLoginClicked(): void {
  if (this.initialized == true) {
     let url = this.authorizationUrl + "?scope=email";
     url = url + "&response_type=" + "code";
     url = url + "&client_id=" + this.clientId;
     url = url + "&access_type=" + "offline";
     url = url + "&redirect_uri=" + this.redirectUrl;
     window.location.href = url;
  }
}

After users have logged in and approved the application, Google invokes the first OpenWhisk action with a ‘code’ parameter. The action knows client id and secret and exchanges the code for an user OAuth access token. After this a second OpenWhisk action, which is in the same action sequence, sends a redirect to the Angular application and passes the token as URL parameter. With the access token protected APIs can be invoked by putting the token in the HTTP request header (see code).

onButtonInvokeActionClicked(): void {
    let headers = new Headers({
      'Content-Type': 'application/json',
      'authorization': 'Bearer ' + this.accessToken
    });
    let options = new RequestOptions({ headers: headers });

    this.http.get(this.protectedUrl, options)
      .map(res => res.json())
      .subscribe(
      result => {
        console.log(result)
        this.resultOfProtectedAPI = JSON.stringify(result, null, 2);
      },
      err => {
        console.error(err);
        this.resultOfProtectedAPI = JSON.stringify(err._body, null, 2);
      });
  }

Check out the complete sample on GitHub.

The slides describe more details.

Check also out the blog from Raymond Camden how to do OAuth with Auth0 and the open source project from Nick Mitchell and Lionel Villard that shows how to use OAuth with OpenWhisk without the API management functionality.