You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现基于用户名的期货资产访问及交易权限限制逻辑?

实现用户资产访问限制的解决方案

现有代码的核心问题

  • 混淆了权限存储对象和查询函数:存储用户权限的是全局对象userPermittedFutures,但在/futures接口中错误地对getPermittedFuturesAssets函数做属性判断,完全无法拿到正确的权限结果
  • 异步逻辑未处理:getPermittedFuturesAssets是异步数据库查询,原代码没有等待查询完成就直接返回结果,大概率会返回空权限
  • 用户信息获取逻辑错误:initializePassport.getCurrentUser()是全局调用,高并发场景下会出现用户信息串扰,express 框架中认证后的用户信息默认存储在req.user中
  • 权限预加载逻辑缺失:没有主动触发getPermittedFuturesAssets的调用,权限数据不会主动写入userPermittedFutures对象

具体实现步骤

1. 改造异步权限查询函数,支持async/await调用

改造后可以等待查询完成后再执行后续逻辑,避免返回空权限:

// 改造为async函数,支持等待查询完成
const getPermittedFuturesAssets = async (traderId) => {
  if (!pgClient) {
    await new Promise(resolve => setTimeout(resolve, 1000));
    return getPermittedFuturesAssets(traderId);
  }
  const query = {
    name: 'fetch-futures-assets-permissions',
    text: 'SELECT trader_id, pair, pair_limit ' +
          'FROM common.accounts_pairs_permits app ' +
          'WHERE exists(SELECT * FROM future.instrument ap WHERE ap.symbol = app.pair) AND trader_id = $1',
    values: [traderId],
  };
  try {
    const res = await pgClient.query(query);
    for (let row of res.rows) {
      addUserFuturesConstraints(row.trader_id, row.pair, row.pair_limit);
    }
    // 返回当前用户的权限列表
    return userPermittedFutures[traderId] || {};
  } catch (err) {
    console.error("Can't get account permitted futures permits. Retrying in a second...");
    await new Promise(resolve => setTimeout(resolve, 1000));
    return getPermittedFuturesAssets(traderId);
  }
}

2. 修复/futures接口逻辑,仅返回用户有权限的资产

app.get('/futures', checkAuthenticated, async (req, res) => {
  try {
    // 从认证信息中取当前用户,避免全局串扰
    const currentUser = req.user.username;
    const traderId = traderIdMnemonicMapping[currentUser];
    if (!traderId) {
      return res.status(403).send({
        status: 'fail',
        message: '未找到对应用户交易权限'
      });
    }

    // 如果本地没有用户权限,先拉取权限
    if (!userPermittedFutures[traderId]) {
      await getPermittedFuturesAssets(traderId);
    }

    // 直接取用户有权限的资产列表返回
    const allowedFuturesAssetsForUser = Object.keys(userPermittedFutures[traderId] || {});
    if (allowedFuturesAssetsForUser.length === 0) {
      console.log("Couldn't find Futures contracts for " + currentUser);
      return res.status(200).send([]);
    }

    res.status(200).send(allowedFuturesAssetsForUser);
  } catch (err) {
    console.log("Failed to get futures portfolios: " + err.message);
    res.status(503).send({
      status: 'fail',
      message: err.message
    });
  }
});

3. 交易接口挂载权限校验中间件

你已经写好了isUserAbleToTradeFutures权限校验中间件,直接挂载到所有需要校验资产权限的交易接口上,就可以自动拦截无权限的交易请求:

// 示例:下单接口挂载权限校验中间件
app.post('/futures/order', checkAuthenticated, isUserAbleToTradeFutures, async (req, res) => {
  // 原有下单逻辑,走到这里的请求都已经通过权限校验
})

可选优化:简化资产权限判断逻辑

不需要遍历对象判断资产是否存在,直接判断对象key是否存在即可,性能更高:

function isFuturesAssetAllowedForUser(username, selectedFutureAsset) {
  const traderId = traderIdMnemonicMapping[username];
  // 直接判断对象是否存在对应key即可,不需要遍历
  return !!userPermittedFutures[traderId]?.[selectedFutureAsset];
}

你现有createUserFuturesAssetsConstraints函数的逻辑已经满足需求,不需要额外修改,它的作用是存储每个资产的交易上限,配合权限校验逻辑使用即可。

内容的提问来源于stack exchange,提问作者user1285928

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 04:09:00