3

我正在使用 koa2 和 koa-router 以及顶部的 sequelize。我希望能够根据他们在数据库中的角色来控制用户访问,并且到目前为止它一直在工作。我做了自己的 RBAC 实现,但遇到了一些麻烦。

如果用户无权访问,我需要在命中任何端点之前退出执行,考虑到端点可以执行任何操作(例如插入新项目等)。这很有意义,我意识到我可能会使用 Sequelize 的事务,但我发现这会增加更多开销并且截止日期即将到来。

到目前为止,我的实现看起来有点像以下:

// initialize.js

initalizeRoutes()
initializeServerMiddleware()

服务器中间件在路由之后注册。

// function initializeRoutes
app.router = require('koa-router')

app.router.use('*', access_control(app))

require('./routes_init')

routes_init 只是运行一个递归解析文件夹并导入所有中间件定义的函数。

// function initializeServerMiddleware
// blah blah bunch of middleware
app.server.use(app.router.routes()).use(app.router.allowedMethods())

这只是普通的 koa-router。

但是,问题出现在 access_control 中。

我有一个文件(access_control_definitions.js),我在其中指定命名路由、它们各自的续集模型名称以及路由存在的规则。(例如,什么角色,如果所有者能够访问他们自己的资源...) 我通过路由参数计算请求者是否拥有资源(例如资源ID 是ctx.params.id)。然而,在这个实现中,params 似乎没有被解析。我认为我必须在 koa-router 之前手动解析参数是不对的。有没有人能够基于此确定一种更好的方法来解决ctx.params未填充实际命名参数的问题?

编辑:我还为此创建了一个 GitHub 问题,考虑到在我看来似乎有一些有趣的事情正在发生。

4

1 回答 1

6

所以如果你看router.js

layerChain = matchedLayers.reduce(function(memo, layer) {
  memo.push(function(ctx, next) {
    ctx.captures = layer.captures(path, ctx.captures);
    ctx.params = layer.params(path, ctx.captures, ctx.params);
    ctx.routerName = layer.name;
    return next();
  });
  return memo.concat(layer.stack);
}, []);

return compose(layerChain)(ctx, next);

它的作用是,对于您拥有的每个路由功能,它都会添加自己的捕获层来生成参数

图层映射

现在这确实有意义,因为您可以为具有不同参数的相同 url 使用两个中间件

router.use('/abc/:did', (ctx, next) => {
    // ctx.router available
    console.log('my request came here too', ctx.params.did)
    if (next)
        next();
});

router.get('/abc/:id', (ctx, next) => {
    console.log('my request came here', ctx.params.id)
});

现在对于第一个处理程序,参数id没有意义,而第二个参数did没有任何意义。这意味着这些参数是特定于处理程序的,并且仅在处理程序内部才有意义。这就是为什么没有你期望的参数是有意义的。我不认为这是一个错误

而且由于您已经找到了解决方法

const fromRouteId = pathToRegexp(ctx._matchedRoute).exec(ctx.captures[0])

你应该使用相同的。或者更好的可能是

var lastMatch = ctx.matched[ctx.matched.length-1];
params = lastMatch.params(ctx.originalUrl, lastMatch.captures(ctx.originalUrl), {})
于 2018-04-09T11:08:09.983 回答