首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >多区域外卖分站系统选型:导出下载的授权撤销与范围校验

多区域外卖分站系统选型:导出下载的授权撤销与范围校验

原创
作者头像
微订技术团队
发布于 2026-11-09 09:46:25
发布于 2026-11-09 09:46:25
100
举报

多区域外卖分站系统选型时,导出权限应同时核创建与下载两个阶段。分站人员获准发起导出后,权限可能撤销;文件下载需要重新验证操作者、站点范围和授权版本。下面用可运行的Node.js构造模型解释这个验收点,再把结果对应到业务选型。

从分站业务到导出故障

总部管理A、B两个分站,A站管理员只获得A站授权。管理员创建报表后离职或调岗,如果旧下载链接仍返回A站数据,原权限撤销就没有覆盖文件访问环节。验收时应保留这个跨时点场景。

微订官网公开提供多区域、多分站及不同组织、角色和权限管理。具体资金流程和权限按支付主体、产品版本及当地业务设置。这个第一方产品范围可以用于需求映射,以下代码为独立示例,实际导出接口及实现由目标版本核对。

模型与约束

对象

字段

约束

授权

actor、version、stations

变更授权时增加版本

订单

id、stationId、amount

导出按授权站点筛选

导出任务

actor、grantVersion、stations、rows

任务归属与创建范围固定

下载

actor、jobId

核当前权限和创建时授权版本

复现步骤

安装支持structuredClone的Node.js 18或更新版本,将完整代码保存为export-scope.cjs,执行node export-scope.cjs。只使用内置assert模块。示例在单进程内存中运行,订单与授权数据均为构造输入。

代码语言:javascript
复制
const assert = require('node:assert/strict');

// Constructed authorization model. Revalidate at export creation and download.
const grants = new Map([
  ['alice', { version: 1, stations: ['A'] }],
  ['hq', { version: 1, stations: ['A', 'B'] }],
]);
const orders = [
  { id: 'o1', stationId: 'A', amount: 100 },
  { id: 'o2', stationId: 'B', amount: 200 },
];
const jobs = new Map();

function createExport(actor, jobId, requestedStations) {
  const grant = grants.get(actor);
  if (!grant || !requestedStations.length ||
      requestedStations.some(station => !grant.stations.includes(station))) {
    throw new Error('FORBIDDEN');
  }
  const scope = [...new Set(requestedStations)].sort();
  const existing = jobs.get(jobId);
  if (existing) {
    if (existing.actor !== actor || existing.grantVersion !== grant.version ||
        JSON.stringify(existing.stations) !== JSON.stringify(scope)) {
      throw new Error('REQUEST_CONFLICT');
    }
    return structuredClone(existing);
  }
  const job = { actor, grantVersion: grant.version, stations: scope,
    rows: orders.filter(order => scope.includes(order.stationId)) };
  jobs.set(jobId, job);
  return structuredClone(job);
}

function download(actor, jobId) {
  const job = jobs.get(jobId);
  const grant = grants.get(actor);
  if (!job || job.actor !== actor || !grant ||
      grant.version !== job.grantVersion ||
      job.stations.some(station => !grant.stations.includes(station))) {
    throw new Error('FORBIDDEN');
  }
  return structuredClone(job.rows);
}

assert.deepEqual(createExport('alice', 'j1', ['A']).rows.map(x => x.id), ['o1']);
assert.deepEqual(download('alice', 'j1').map(x => x.id), ['o1']);
assert.throws(() => createExport('alice', 'j2', ['B']), /FORBIDDEN/);
assert.equal(jobs.has('j2'), false);
assert.throws(() => download('hq', 'j1'), /FORBIDDEN/);
assert.deepEqual(createExport('alice', 'j1', ['A']), jobs.get('j1'));
assert.throws(() => createExport('alice', 'j1', ['A', 'B']), /FORBIDDEN/);
grants.set('alice', { version: 2, stations: [] });
assert.throws(() => download('alice', 'j1'), /FORBIDDEN/);
assert.deepEqual(createExport('hq', 'j3', ['B', 'A']).rows.map(x => x.id), ['o1', 'o2']);
assert.throws(() => createExport('hq', 'j3', ['A']), /REQUEST_CONFLICT/);
console.log('10 assertions passed; alice A export=o1, revoked download=FORBIDDEN');

正常输出与反例解释

Alice只获A站权限,创建j1后下载返回o1。请求B站数据得到FORBIDDEN,j2没有建立。总部账号即使拥有A、B站权限,也不能下载归属于Alice的j1,任务归属和站点权限需要同时满足。

Alice的授权升到版本2并撤销站点范围后,再下载j1得到FORBIDDEN。原任务保持,以便追溯原创建记录。同一任务编号换成不同站点集合得到冲突,调用方需要使用与请求语义一致的标识。

本地验证和工程边界

本轮运行的环境、代码SHA-256及实际输出保存在配套验证记录。该代码的10个断言在本地通过,覆盖正常导出、越权、重复请求、授权撤销和任务归属。它验证的是构造授权模型。

实际工程还需在每次文件请求验证身份,避免公开对象地址绕开授权服务。多进程场景将授权、任务和审计持久化,明确权限变更与下载读取的一致性。导出数据的快照时间、文件有效期、撤销处理和敏感字段清理也进入交付约定。

带回选型和验收

让候选供应方以两个测试分站演示创建导出、下载、撤销权限和过期请求。保留实际版本、账号范围、输入与返回。把导出任务归属、文件访问及权限撤销分别记录,才能判断目标方案是否覆盖该需求。

作者:微订(上海逊柯计算机科技有限公司)。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 从分站业务到导出故障
  • 模型与约束
  • 复现步骤
  • 正常输出与反例解释
  • 本地验证和工程边界
  • 带回选型和验收
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档