Tech Blog

Using a simple proxy to add CORS support to Ex Libris APIs

Browser security prevents HTTP requests from being made between domains. This “same-origin policy” prevents sensitive information from being revealed to an untrusted party. However, the policy makes it challenging to build JavaScript-based web applications, where AJAX requests are made to a server to retrieve data and display it on the web page. If we want to retrieve data from a different server than the one hosting our web page, the server must support CORS. CORS (Cross-Origin Resource Sharing) allows HTTP requests to be made from a web page to a URL on another domain.

We’ve discussed support for CORS in a previous blog post. Since Ex Libris APIs require an API key, calling the APIs from the browser means that the key will be exposed in the client code. This is not best practice from a security perspective. A better alternative is to use a proxy which adds the API key before forwarding the API call to Alma. The diagram below shows how a proxy can be used to avoid exposing the API key to the client.

While as of this writing, CORS is supported for the Analytics APIs and for all Primo REST APIs, we recommend the proxy approach to avoid unauthorized use of your API keys.

Simple CORS Proxy

This Docker image includes the Nginx proxy server and configuration which adds the API key from the environment and forwards the request to Alma. The response includes CORS headers so that it can be called from client-side applications. Note that Alma APIs can be called from anywhere using this proxy, so you’ll want to define your API key narrowly and consider adding additional limitations to the proxy configuration to define which APIs can be called.

The Docker image can be run locally as follows:

$ docker build -t alma-proxy .

$ docker run --name alma-proxy -p 5555:5555 -e ALMA_API_KEY=l7xx.... -e PORT=5555 --rm -it alma-proxy

Deploy to Heroku

Alternatively, the image can be deployed to the Heroku platform using the “Deploy to Heroku” button on the Github page. This provides an easy way to host the proxy in the public cloud.

Once the image has been deployed, I can make API calls via the new URL. Note the CORS headers in the response.

$ curl -v https://alma-cors-proxy.herokuapp.com/almaws/v1/users
> GET /almaws/v1/users HTTP/1.1
> Host: alma-cors-proxy.herokuapp.com
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< X-Exl-Api-Remaining: 14763
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
< Access-Control-Allow-Headers: Origin,Accept,Content-Type
< 
* Connection #0 to host alma-cors-proxy.herokuapp.com left intact
{"user":[{"primary_id":"00469004","first_name":"GregWaltersAAA","last_name":"00469004","gender":{"value":"","desc":""},"password":"","status":{"value":"ACTIVE","desc":"Active"},"requests":null,"loans":null,"fees":null,"researcher":null,"link":"https://alma-cors-proxy.herokuapp.com/almaws/v1/users/00469004"}],"total_record_count":1427}

Let us know in the comments if this approach is helpful to you, or if you use an alternative solution for accessing the Alma APIs via client apps.