Skip to content

分享模式篇

目标:让集成方编排两条分享路径——面向已知身份接收方的站内分享(ShareGrant),以及面向不特定访问方的公开链接(ShareLink),理解各自的权限预设、token 契约、公开下载流,并规避常见坑。

不在本篇范围:分享按钮 UI 实现(集成方业务 UI 层,不在 ATKONBASE 对外能力范围);ACL 权限位与继承(见 ACL 与继承模式篇);资源生命周期(TRASHED 状态对分享的影响见 生命周期模式篇);错误码完整码表(见错误码参考)。

本篇覆盖三个对外面:V1 ShareGrant 端点(强身份,站内)、V1 ShareLink 端点(链接管理)、公开匿名下载端点 /public/s/{tenantCode}/{token}/...(无需登录的消费侧)。

关键事实

  • 两条路径互不依赖:ShareGrant 授予指定 grantee,ShareLink 签发可分发的不透明 token;两者可以同时并用于同一资源。
  • ShareLink 的 token不透明字符串——不应尝试解析、拆分或在 URL 之外位置存储。
  • 公开链接读侧要求 DOWNLOAD 位授予permissionBits 未含 2(DOWNLOAD)的 ShareLink,访问 /public/s/.../meta/download 统一返回不可用响应——这是设计约束。集成方按需选择仅 READ(仅元数据可达,字节下载受限)或 READ + DOWNLOAD(完整公开下载)。
  • ShareGrant 采用预设白名单:权限只能在 VIEW(READ + DOWNLOAD)或 EDIT(READ + DOWNLOAD + WRITE)中选一,不接受裸位掩码。
  • 站内分享的 grantor 始终是调用方代表的用户(由身份上下文解析),不可指定。
  • tenantCode 是租户对外识别码(全局唯一短字符串),token 在租户作用域内唯一;两者共同定位到一条 share_link 记录。
  • CONTAINER 类型的 ShareLink 支持目录浏览(/list)和按 path 参数逐层下载;DOCUMENT / VERSION 类型不支持浏览,/list 返回 174001 SHARE_LINK_UNAVAILABLE

一、站内分享(ShareGrant)

ShareGrant 授权给 ATKONBASE 内部已知的用户 / 角色 / 部门,grantor 推拉消息由集成方业务层负责(平台不发通知)。

创建或覆盖更新(POST /v1/share-grants/save

同一 (resourceType, resourceId, grantee) 已存在活跃 grant 时语义为覆盖更新(不会新增重复条目)。

bash
curl -X POST 'https://api.atkonbase.example.com/v1/share-grants/save' \
  -H 'Authorization: Bearer ${accessToken}' \
  -H 'X-Atk-User-Token: ${userToken}' \
  -H 'Content-Type: application/json' \
  -d '{
    "resourceType": "DOCUMENT",
    "resourceId": "${docId}",
    "grantee": {
      "granteeType": "USER",
      "granteeId": "${targetUserId}"
    },
    "permissionPreset": "VIEW",
    "expiresAt": "2026-12-31T23:59:59.000+08:00",
    "message": "请查看这份合同草稿"
  }'
  • resourceType 取值 DOCUMENT / CONTAINER
  • permissionPreset 取值 VIEW(等价 READ + DOWNLOAD)或 EDIT(READ + DOWNLOAD + WRITE)。
  • granteeType 取值 USER / ROLE / DEPARTMENTgranteeId 是 ATKONBASE 内部稳定 ID(见 认证与身份双通道模式篇 §granteeId 解析)。
  • expiresAt=null 表示永不过期;不得晚于平台允许的最大 TTL(超出返 code=1)。

期望响应(关键字段)

json
{
  "code": 0,
  "data": {
    "shareGrantId": "SG1000001",
    "resourceType": "DOCUMENT",
    "resourceId": "${docId}",
    "grantorId": "${currentUserId}",
    "granteeType": "USER",
    "granteeId": "${targetUserId}",
    "permissionPreset": "VIEW",
    "message": "请查看这份合同草稿",
    "expiresAt": "2026-12-31T23:59:59.000+08:00",
    "status": "ACTIVE",
    "createTime": "2026-05-28T10:00:00.000+08:00"
  }
}
  • status 取值 ACTIVE / EXPIRED / REVOKED

更新(POST /v1/share-grants/update

仅允许改 permissionPreset / expiresAt / message

bash
curl -X POST 'https://api.atkonbase.example.com/v1/share-grants/update' \
  -H 'Authorization: Bearer ${accessToken}' \
  -H 'X-Atk-User-Token: ${userToken}' \
  -H 'Content-Type: application/json' \
  -d '{
    "shareGrantId": "${shareGrantId}",
    "permissionPreset": "EDIT",
    "expiresAt": null
  }'

撤销(GET /v1/share-grants/delete?shareGrantId=...

创建者本人可撤销;grantee 无权撤销对自己的分享。

bash
curl -X GET 'https://api.atkonbase.example.com/v1/share-grants/delete?shareGrantId=${shareGrantId}' \
  -H 'Authorization: Bearer ${accessToken}' \
  -H 'X-Atk-User-Token: ${userToken}'

查询分享列表

端点含义
POST /v1/share-grants/getOutgoingPage当前用户分享出去的列表
POST /v1/share-grants/getIncomingPage分享给当前用户的列表
GET /v1/share-grants/{shareGrantId}单条详情(grantor 或 grantee 均可查)
bash
curl -X POST 'https://api.atkonbase.example.com/v1/share-grants/getOutgoingPage' \
  -H 'Authorization: Bearer ${accessToken}' \
  -H 'X-Atk-User-Token: ${userToken}' \
  -H 'Content-Type: application/json' \
  -d '{ "pageSize": 20, "pageNumber": 1 }'

ShareLink 生成一个不透明 token,集成方把 url 字段(完整可分发 URL)暴露给用户;访问者无需登录。

创建 ShareLink(POST /v1/share-links/save

bash
curl -X POST 'https://api.atkonbase.example.com/v1/share-links/save' \
  -H 'Authorization: Bearer ${accessToken}' \
  -H 'Content-Type: application/json' \
  -d '{
    "resourceType": "DOCUMENT",
    "resourceId": "${docId}",
    "permissionBits": 3,
    "ttlSeconds": 604800,
    "password": "abc123",
    "maxAccessCount": 100
  }'
  • resourceType 取值 DOCUMENT / VERSION / CONTAINER
  • permissionBits1=READ(仅元数据可达)、2=DOWNLOAD(仅字节下载,不含元数据)、3=READ+DOWNLOAD(完整公开下载)。⚠️ 不含 DOWNLOAD 位时,访问 /download 返回 174001 SHARE_LINK_UNAVAILABLE,这是约束设计——不是服务端错误。
  • ttlSeconds=null 表示链接永不过期。
  • password 可选;设置后访问侧需先调 /verify 端点验证密码(见 §三)。
  • maxAccessCount 可选;访问次数超限后链接自动失效。
  • 所需 scope:client:storage:share-link:create

期望响应(关键字段)

json
{
  "code": 0,
  "data": {
    "shareLinkId": "SL1000001",
    "token": "abc1def2ghi3",
    "url": "https://api.atkonbase.example.com/public/s/${tenantCode}/abc1def2ghi3",
    "resourceType": "DOCUMENT",
    "resourceId": "${docId}",
    "permissionBits": 3,
    "expiresAt": "2026-06-04T10:00:00.000+08:00",
    "maxAccessCount": 100,
    "remainingCount": 100,
    "requiresPassword": true,
    "createTime": "2026-05-28T10:00:00.000+08:00"
  }
}
  • token —— 不透明字符串,不可解析内部结构,不应在 URL 之外位置存储或转发。
  • url —— 完整可分发 URL;集成方直接把此字段的值暴露给用户,不要自行拼接路径。
  • remainingCount —— 剩余可访问次数;未设置 maxAccessCount 时为 null
  • requiresPassword —— 是否需要验证密码(访问侧参考此字段决定是否展示密码输入框)。

查询与撤销

bash
# 分页查我的 ShareLink
curl -X POST 'https://api.atkonbase.example.com/v1/share-links/getPage' \
  -H 'Authorization: Bearer ${accessToken}' \
  -H 'Content-Type: application/json' \
  -d '{ "pageSize": 20, "pageNumber": 1 }'

# 撤销
curl -X GET 'https://api.atkonbase.example.com/v1/share-links/delete?shareLinkId=${shareLinkId}' \
  -H 'Authorization: Bearer ${accessToken}'

# 详情
curl -X GET 'https://api.atkonbase.example.com/v1/share-links/${shareLinkId}' \
  -H 'Authorization: Bearer ${accessToken}'

撤销后 token 立即失效;访问侧返回 174001 SHARE_LINK_UNAVAILABLE

三、公开匿名下载流(/public/s/{tenantCode}/{token}/...

公开端点无需 Authorization header,适合嵌入浏览器直接访问或 iframe 渲染。

获取元信息

bash
curl -X GET 'https://api.atkonbase.example.com/public/s/${tenantCode}/${token}'

返回 PublicShareMetaDTO,包含资源类型、标题、文件名、权限位、是否需要密码、剩余次数等。

验证密码(有密码的链接)

bash
curl -X POST 'https://api.atkonbase.example.com/public/s/${tenantCode}/${token}/verify' \
  -H 'Content-Type: application/json' \
  -d '{ "password": "abc123" }'

验证通过返回 code=0;密码错误返回 174010 PASSWORD_INVALID;链接未设密码却传了密码返回 174011 PASSWORD_NOT_REQUIRED。消费侧应先检查 ShareLinkResultDTO.requiresPassword 字段,仅在 requiresPassword=true 时展示密码输入框并调 /verify

浏览容器(仅 CONTAINER 类型)

bash
curl -X GET 'https://api.atkonbase.example.com/public/s/${tenantCode}/${token}/list?path=${subPath}&page=1&size=20'
  • path 可选,指向容器下某一层子容器(按业务命名路径,如 folder-a/sub-b)。
  • DOCUMENT / VERSION 类型的 ShareLink 调用 /list 一律返回 174001 SHARE_LINK_UNAVAILABLE

下载

bash
curl -X GET 'https://api.atkonbase.example.com/public/s/${tenantCode}/${token}/download?path=${docPath}'
  • DOCUMENT / VERSION 类型忽略 path(直接下载该资源)。
  • CONTAINER 类型必须传 path 指向子树内某个文档;path 无效(不在子树内 / 对应资源已不存在)返回 174014 SHARE_LINK_PATH_INVALID,建议先调 /list 获取合法路径再下载。
  • 链接不可用统一返回 174001 SHARE_LINK_UNAVAILABLE(不区分具体原因以抗探测)。下载失败时,携带响应中的 rid / X-Request-Id 联系 ATKONBASE 支持团队。

⚠️ 公开链接不是客户端签名 URL(非 S3 风格预签名 URL)——集成方不需要也不应该在客户端计算任何签名。url 字段即完整可用 URL,直接使用即可。

四、ShareGrant 与 ACL 的关系

ShareGrant 是叠加授权,不是 ACL 替代品:

  • ShareGrant 授予的 VIEW / EDIT 预设是叠加在资源现有 ACL 之上的额外权限——即使 grantee 在资源 ACL 中没有任何条目,ShareGrant 也让他临时可读 / 可写。
  • ShareGrant 到期或撤销后,grantee 回退到资源 ACL 决定的权限——如果 ACL 里也没有条目,则无权访问。
  • ⚠️ ShareGrant 不继承 ACL 树:它只作用于被授权的那一条资源(resourceId),不沿容器→文档继承传播。
  • 详细权限位定义与 ACL 继承规则见 ACL 与继承模式篇

常见错误码

鉴权创建链路(/v1/share-links/* / /v1/share-grants/*):

名称含义参考
174005SHARE_RESOURCE_NOT_FOUND分享资源不存在(创建 ShareLink 时)share-174
174006SHARE_RESOURCE_TYPE_UNSUPPORTED分享资源类型不支持share-174
174007SHARE_TOKEN_GENERATION_FAILEDtoken 生成失败(服务端异常,重试或联系支持)share-174

公开分享消费侧(/public/s/{tenantCode}/{token}/...):

名称含义参考
174001SHARE_LINK_UNAVAILABLE链接不可用(不区分具体原因以抗探测)share-174
174008SHARE_LINK_QUOTA_EXCEEDED访问次数超出 maxAccessCountshare-174
174009PASSWORD_REQUIRED需要密码但未携带(先调 /verifyshare-174
174010PASSWORD_INVALID密码错误share-174
174011PASSWORD_NOT_REQUIRED未设密码却传了密码(先看 requiresPasswordshare-174
174013IP_NOT_ALLOWED访问方 IP 不在白名单内share-174
174014SHARE_LINK_PATH_INVALIDCONTAINER 分享 path 参数无效share-174

常见坑

  • ⚠️ 创建 ShareLink 时 permissionBits 只含 READ(1)却期望对方能下载文件:公开链路下载要求 DOWNLOAD 位(2);仅 READ 链接访问 /download 统一返回不可用响应——这是设计约束。如需完整公开下载,创建时将 permissionBits 设为 3(READ + DOWNLOAD)。
  • ⚠️ 尝试解析 token 结构:token 是平台内部不透明字符串,格式可能随时变化,不应依赖其任何结构属性。
  • ⚠️ /download 端点替代 /list 浏览容器:CONTAINER 类型分享不能直接 download 容器本身,需先通过 /list 拿到子文档列表,再按 path 下载具体文档。
  • ⚠️ grantee 传 IdP 侧 openId / unionIdgranteeId 是 ATKONBASE 内部稳定 ID,不是 IdP 原始主键。取法见 认证与身份双通道模式篇
  • ⚠️ ShareGrant 的 permissionPreset 与 ACL role 混用:ShareGrant 预设是临时叠加,不同于 ACL set 端点的 role 参数——两者独立维护,不要假设一方变更会同步影响另一方。
  • ⚠️ CONTAINER 类型 ShareLink /list 返回不可用响应误以为链接失效:DOCUMENT / VERSION 类型确实不支持浏览,这是正常行为;检查 resourceType 字段。

下一步