question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Middleware used in a nested router is evaluated on unrelated routes.

See original GitHub issue

Descriptions

The middleware used in a nested-router can be triggered if the regexp matches (matchedRoute) with the unrelated path. The behavior is something intuitive or not easily predictable.

I wrote one router like this, intending to run “checkAuth” middleware when the user accesses to /a/1 or any other subroutes written under /a.

function createAjaxRouter() {
  const router = createRouter('/a');
  router.use(checkAuth);
  router.get('/1', routeHandler(1))
  return router.routes();
}

However, accessing /about (defined elsewhere) can trigger “checkAuth”. This is because middleware is evaluated when the request-path matches /a(.*).

This issue can be avoided by defining the routes /about before this nested router, but manually managing the order of nested routes is difficult.

I wonder if the library can guarantee that middleware used inside the nested-routes are used only in nested routes.

Environment

node.js version: v11.6.0 (Windows) npm/yarn and version: 6.14.5 @koa/router version: 9.0.1 koa version: 2.12.0

Code sample:

const Koa = require('koa');
const Router = require('@koa/router');

function createRouter(prefix) {
  return new Router({
    prefix
  });
}

function routeHandler(x) { 
  return async ctx => {
    console.log(x);
    ctx.body = `${x}`;
  }
}

async function checkAuth(ctx, next) {
  console.log('checkAuth');
  // if (ctx.query['auth'] != "1") {
  //   throw new Error("not authed");
  // }
  await next();
}

function createAjaxRouter() {
  // match for '/a(.*)'
  const router = createRouter('/a');
  router.use(checkAuth);
  router.get('/1', routeHandler(1))
  return router.routes();
}

function createIndexRouter() {
  // match for '(.*)'
  const router = createRouter();
  router.get('/', routeHandler('index'));
  router.get('/about', routeHandler('about'));
  return router.routes();
}

function setRouter(app) {
  // match for '(.*)'
  const router = createRouter();
  router.use(createAjaxRouter());
  router.use(createIndexRouter());

  // order of path in routes.router.stack =>
  // ['/a(.*)', '/a/1', '/', '/about']
  const routes = router.routes();
  app.use(router.routes());
  app.use(router.allowedMethods());
}

const app = new Koa();
setRouter(app);
app.listen(3010); 

Gist

Expected Behavior:

Access to /about should not run the middleware used for nested routes with prefix: /a

Actual Behavior:

Access to /about can trigger the middleware defined in the nested routes.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:7

github_iconTop GitHub Comments

1reaction
julienwcommented, Jul 23, 2020

Looks interesting, thanks for the pointer !

0reactions
nightlyherbcommented, Dec 22, 2021

I think #44 is orthogonal to this issue.

That issue is about the Router.used middleware not executing when no paths are matched. In order to solve that one needs to use router.(get|post|...|all) instead.

This issue is about Router.used middleware on “inner router 1” executing on a match in “inner router 2”, which, I suspect, is because there is no “local scope” for the inner routers. (This is what I intended with Item 1, although it doesn’t seem very clear on second read)

Still, thank you for your input.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Extracting MatchedPath in middleware will not always give the ...
When extracting MatchedPath in middleware, it may not have the correct value if the request end up being handled by a nested Router...
Read more >
nested routes in expressJS - Stack Overflow
You can't nest routes. Doing so creates havoc. At first, the route is not even active until the parent route is hit first...
Read more >
Error handling in Express
Normally you'll have routes, possibly with further nested routes, but the process for ... Passing errors to the error handling middleware.
Read more >
Routing - Fiber
Routing refers to how an application's endpoints (URIs) respond to client requests. Paths.
Read more >
Express.js Middleware Can Be Arbitrarily Nested Within A ...
// Try nesting a Router as middleware (with internally nested middleware). express.Router() .use(.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found