CORS Support

Brian edited this page Dec 11, 2016 · 3 revisions

The core of the platform does not provide a mechanism to control CORS. Instead, the platform allows for developers to control which end-points are available to other domains by wildcarding routes. Developers can also enable CORS support at a global routing level. An example can be found here.

Developers will need to create a controller for their plugin(s) that register the route patterns that should be provided for their CORS requests. The real trick is to ensure that the Access-Control-Allow-Origin header is appropriately set for each end-point that will be shared across origins. This will have to be in two places:

  1. In a controller that will handle the OPTIONS request (Pre-flighted).
  2. In the controller that renders your API end-point as a custom header as shown below. This will only apply to the non-preflight requests. However, it is a good idea to include in the end-point implementations that will be conered by the OPTIONS requests in the event other formats are used.

A good resource to identify when the pre-flighted requests will be used can be found here.

Here is the link to the Gist.

The snippet of code below demonstrates how to include the access control header for incoming options requests.

/*
    Copyright (C) 2015  PencilBlue, LLC

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

module.exports = function(pb) {

    //PB dependencies
    var util           = pb.util;
    var BaseController = pb.BaseController;
    var PluginService  = pb.PluginService;

    /**
     * CORS Controller - A sample controller to demonstrate how open up API endpoints for cross domain requests
     * 
     * @class CorsApiController
     * @constructor
     * @extends BaseController
     */
    function CorsApiController(){}
    util.inherits(CorsApiController, BaseController);

    /**
     * The handler for responding to the options request
     * @method render
     * @param {Function} cb
     */
    CorsApiController.prototype.render = function(cb) {
        var result = {
            content: '',
            headers: {
                'Access-Control-Allow-Origin': "*"
            }
        };
        cb(result);
    };
    
    /**
     * Provides the routes that are to be handled by an instance of this prototype.  
     * The route provides a definition of path, permissions, authentication, and 
     * expected content type. In this particular case we are building a simple 
     * API with no special CRUD operations.  Therefore, we can leverage the 
     * power of the BaseApiController and let it do the heavy lifting for us.  
     * All we have to do is define the routes.
     * Method is optional
     * Path is required
     * Permissions are optional
     * Access levels are optional
     * Content type is optional
     * 
     * @param cb A callback of the form: cb(error, array of objects)
     */
    CorsApiController.getRoutes = function(cb) {
        var routes = [
            {
                //opens up all endpoints
                method: 'options',
                path: "*",
                handler: "render",
                auth_required: false,
            },
            {
                //opens up all endpoints under a the API prefix
                method: 'options',
                path: "/api/*",
                handler: "render",
                auth_required: false,
            },
            {
                //opens up a specific end-point
                method: 'options',
                path: "/api/articles",
                handler: "render",
                auth_required: false,
            },
        ];
        cb(null, routes);
    };

    //exports
    return CorsApiController;
};
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.