Reaching Outside Your App

While Cloud Apps are meant to exist as stand-alone apps which interact with Alma, there are times where an app has to reach outside and interact with external services. For example, your app may retrieve data from a webservice or show content from an external website. In order to provide a secure, trusted environment, Cloud Apps are “sandboxed,” meaning they cannot by default reach outside without specifying the app’s requirements explicitly in the manifest.

In this tutorial, we’ll walk through the configuration required to call the Hathitrust Bibliographic API to retrieve information about volumes in their repository.

First, we’ll follow the instructions in the “Adding additional routes” tutorial to add a new component and route called “external”.

Connect Source

Our component template includes a simple web form which includes a select box of the identifier types supported by the Hathitrust API and a text box for the identifier. The search button is hooked up to a search method.

external.component.htmlView on Github

The second part of our template includes the display for the data we retrieve from the webservice.

external.component.htmlView on Github

Our search method calls the Hathitrust API and maps the response into an object that we store in a record property of the component. This is what the template uses to display the response from Hathitrust.

external.component.tsView on Github

 

The interesting part of this example, though, is the manifest file. Without adding the appropriate configuration in the manifest, we will not be able to make the outbound call to Hathitrust. We would see an error message similar to the following in the browser console:

Refused to connect to 'https://catalog.hathitrust.org/api/volumes/brief/isbn/0394530934.json' because it violates the following Content Security Policy directive: "connect-src 'self'".

To resolve this error, we’ll add the following to our manifest.json file:

"contentSecurity": {
   "connectSrc": [
      "https://catalog.hathitrust.org/"
   ]
}

Now our app is able to make calls to endpoints which begin with https://catalog.hathitrust.org/.

Browser Sandbox

In our template we include a link to the record view in the Hathitrust catalog which will open in a new browser tab. By default, Cloud Apps are sandboxed and cannot open popup windows without explicitly setting the configuration in the manifest. So within the contentSecurity section we add a sandbox attribute as follows:

"sandbox": {
   "popups": true
}

Now clicking on the link will open the page in a new tab.

Other properties

Other properties of the contentSecurity section of the manifest allow us to reach outside of our app in different ways, including:

  • Displaying content from other websites in an iframe with the frameSrc property
  • Displaying modals (confirm, prompt) or pop-up windows with the sandbox property.

See the manifest documentation for the full details.

Authentication Token

To communicate with external services that require authentication, the Cloud Apps API provides an authentication token (from the August 2020 release) as a signed JSON Web Token (JWT). For technical details on the token and how to verify it, see this documentation. Your app can use the authentication with a custom service that you have written. If you’re using an existing service that requires credentials, you can create a proxy that validates the token to ensure the request came from your Cloud App, and then forward the request to the third-party service with the required credentials.

In this part of the tutorial, we will be using the Hathitrust Data API. Unlike the Hathitrust Bibliographic API, the data API requires authentication with credentials that can be obtained at the Hathitrust key service. We’ve created a proxy which accepts requests and adds OAuth 1.0a signature parameters before forwarding the request to the Hathitrust API. We’ve also created an authorizer function which validates a Cloud App token. With this combination, we can now make the authenticated API available to our app to retrieve metadata about a record including the number of pages, and display the scanned pages from the Hathitrust repository.

We’ve added a call to the getAuthToken method of the Events Service in our init function. We then display a field for the Hathitrust identifier and a button to call the data API. In the dataApi method, we then create an Authorization header with the keyword Bearer and our token. We send that token along with our request to the Data API proxy. We parse the response and use it to populate a list of page scan images to display. We also display a button which opens the images in a lightbox. The images are retrieved using the same Data API proxy and authentication header.

external.component.tsView on Github

Of course, we need to add the URL of our service to the connectSrc property of the manifest, as we outline above.

We can use this pattern to communicate with any external service. You can reuse the Hathitrust proxy for your own institution using your credentials. If you’re using the AWS API Gateway to host your proxy, you can reuse the authorizer function. See the readme for more details on how to deploy the service to your environment.