Using CORS with Restify in NodeJS
Restify is Express without the cruft of a full-fledged back-end framework, and it provides a valuable way to prototype web services to get things up-and-running quickly. It also provides a solid number of plugins to enhance back-end capabilities, such as easily parsing body and query string fields into variables.
With Restify, you might want to stand up an API, but then check on that API via a single page application. These applications could each exist in testing on a different URL or port. For example, you could be running Restify on port 3000, but have a single page application consuming the web services via port 8080, or some IIS Express port. If you attempt to connect to your API endpoint via JavaScript in the single page application, you're likely to see an error somewhat to the effect of:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:3000/api/EPA?ComputingID=aa4aa. (Reason: CORS header 'Access-Control-Allow-Origin' missing).
Even if you're client application is set up to enable CORS, your server application needs to be configured as well. Restify--at one time--included this out-of-the-box--available via restify.CORS()
, but that's no longer the case. Now you must include a third-party middleware component.
To install:
npm install restify-cors-middleware --save
For TypeScript users, you can get the typings via DefinitelyTyped using the NPM scope:
npm install @types/restify-cors-middleware --save-dev
Once installed, in your main Restify file (mine is called app.ts
), you can import the CORS middleware (I'm using TypeScript here):
import * as corsMiddleware from "restify-cors-middleware";
Once imported, create your CORS object:
const cors = corsMiddleware({
origins: ["*"],
allowHeaders: ["Authorization"],
exposeHeaders: ["Authorization"]
});
For testing, I'm just allowing origins from everywhere with the *
wildcard. For production, you're probably going to want to restrict access. For the two header options, I'm asking for the "Authorization" header to be available since I'm authenticating via a JSON Web Token (JWT), and will need access to the Authorization Bearer header.
Lastly, you'll need to use the pre()
and use()
methods to set up the middleware for the Restify server (my example assumes the Restify server is a variable named server
):
server.pre(cors.preflight);
server.use(cors.actual);
The first sets up preflight requests, while the second adds the appropriate support for the normal requests.
Once set up, you should be able to access your API via a secondary localhost application on a different port.