koajs/cors

Its posible to use this plugin on a specific (set of ) routes instead of globally?

develmts opened this issue · 9 comments

Specifically:

Can I do

const cors = require ('kcors');
var optCors = { 'some':'set','of':'options' }
var router = require('koa-router')({prefix: '/api'});
router.use( cors ( {optCors} ) );

or even

router.get('/someUrl', cors(), function* (next){
// some processing
})

instead of the standard documented app.use(cors())

Should be possible, since this is just middleware.

Note that CORS requests use the HTTP OPTIONS* method instead of GET, so it may not work if you only bind it to GET.

Curiously, the issue solved one I created fake route for the OPTIONS http verb, for the same route that was failing before. I need to investigate why

Anyway, thanks for your configmation

@develmts Whoops, of course it was OPTIONS, not HEAD. 🙁

But supposedly the koa-router should manage this automatically with the router.allowedMethods(), true?

@develmts I don't think so. You're explicitly telling it to only use GET. I'd probably submit a bug report if it listens to OPTIONS without me allowing that.

As per koa-router Github Home

router.allowedMethods([options]) ⇒ function

Returns separate middleware for responding to OPTIONS requests with an Allow header containing the
allowed methods, as well as responding with 405 Method Not Allowed and 501 Not Implemented as
appropriate.

@develmts Interesting, thanks.

For anyone else coming to this issue, I had some real trouble getting koa/cors & koa-router to play nicely.

In the end I did something like this:

router.all('/mypath', cors({
  origin: (ctx) => {
    const requestOrigin = ctx.get('Origin');
    if (someKindOfTest(requestOrigin)) {
      return requestOrigin;
    }
    return '';
  },
  allowMethods: 'GET,OPTIONS'
}));

Note the use of all() which lets koa-router accept pre-flight OPTIONS calls. If you use...use() you encounter these open issues with koa-router v7: https://github.com/ZijianHe/koa-router/labels/always%20call%20middleware.

Don't forget to add OPTIONS to allowMethods too.

As an aside; in an example in the test file for koa/cors you return false instead of an empty string to indicate that the origin is not allowed. But I'm writing TypeScript and because of the later call to ctx.set() which requires a string as a second argument (the value of the header), it shouldn't really be returning false (it's also not allowed by @types/koa__cors). I appreciate that's a strict typing issue, but I think it would be beneficial to have some clarification in the README as to what the expected return value of the origin function should be.

@jalada worked for me and saved me a bunch of time, really appreciate it.