swagger: allow cross-origin requests

Add CORS middleware to the swagger app.

Add a configuration option allowing developers to disable CORS.
This commit is contained in:
Miroslav Bajtoš 2014-10-07 09:19:44 +02:00
parent 64c25a8c3c
commit f645c6db0d
3 changed files with 41 additions and 4 deletions

View File

@ -12,6 +12,7 @@ var urlJoin = require('./url-join');
var _defaults = require('lodash.defaults');
var classHelper = require('./class-helper');
var routeHelper = require('./route-helper');
var cors = require('cors');
/**
* Create a remotable Swagger module for plugging into `RemoteObjects`.
@ -38,6 +39,8 @@ function Swagger(loopbackApplication, swaggerApp, opts) {
var routes = adapter.allRoutes();
var classes = remotes.classes();
setupCors(swaggerApp, remotes);
// These are the docs we will be sending from the /swagger endpoints.
var resourceDoc = generateResourceDoc(opts);
var apiDocs = {};
@ -70,13 +73,20 @@ function Swagger(loopbackApplication, swaggerApp, opts) {
});
/**
* The topmost Swagger resource is a description of all (non-Swagger)
* resources available on the system, and where to find more
* The topmost Swagger resource is a description of all (non-Swagger)
* resources available on the system, and where to find more
* information about them.
*/
addRoute(swaggerApp, opts.resourcePath, resourceDoc, opts);
}
function setupCors(swaggerApp, remotes) {
var corsOptions = remotes.options && remotes.options.cors ||
{ origin: true, credentials: true };
swaggerApp.use(cors(corsOptions));
}
/**
* Add a route to this remoting extension.
* @param {Application} app Express application.

View File

@ -31,10 +31,11 @@
"url": "https://github.com/strongloop/loopback-explorer/blob/master/LICENSE"
},
"dependencies": {
"swagger-ui": "~2.0.18",
"cors": "^2.4.2",
"debug": "~1.0.3",
"express": "3.x",
"lodash.clonedeep": "^2.4.1",
"lodash.defaults": "^2.4.1",
"express": "3.x"
"swagger-ui": "~2.0.18"
}
}

View File

@ -106,6 +106,31 @@ describe('swagger definition', function() {
});
});
describe('Cross-origin resource sharing', function() {
it('allows cross-origin requests by default', function(done) {
var app = mountSwagger();
request(app)
.options('/explorer/resources')
.set('Origin', 'http://example.com/')
.expect('Access-Control-Allow-Origin', /^http:\/\/example.com\/|\*/)
.expect('Access-Control-Allow-Methods', /\bGET\b/)
.end(done);
});
it('can be disabled by configuration', function(done) {
var app = mountSwagger({}, { remoting: { cors: { origin: false } } });
request(app)
.options('/explorer/resources')
.end(function(err, res) {
if (err) return done(err);
var allowOrigin = res.get('Access-Control-Allow-Origin');
expect(allowOrigin, 'Access-Control-Allow-Origin')
.to.equal(undefined);
done();
});
});
});
function getSwaggerResources(app, restPath, classPath) {
return request(app)
.get(urlJoin(restPath || '/explorer', '/resources', classPath || ''))
@ -122,6 +147,7 @@ describe('swagger definition', function() {
addlOptions = addlOptions || {};
var app = createLoopbackAppWithModel(addlOptions.apiRoot);
var swaggerApp = express();
if (addlOptions.remoting) app.set('remoting', addlOptions.remoting);
swagger(app, swaggerApp, options);
app.use(addlOptions.explorerRoot || '/explorer', swaggerApp);
return app;