1. 02. 鉴权与安全
石墨文档中台-开发文档
  • 1. 适用范围
  • 00. 概述
    • 石墨文档中台能做什么?
    • 三种典型的业务接入场景
    • 石墨文档中台支持哪些格式?
  • 01. 快速开始
    • 基本概念
    • 场景一:10 分钟创建预览文件
    • 场景二:10 分钟创建协同编辑文件
  • 02. 鉴权与安全
    • 整体概述
    • 签名凭证 Token
    • 签名凭证 Signature
  • 03. 文件预览
    • 整体概述
    • 如何预热预览缓存
    • 如何防盗链
    • 常见问题处理
  • 04. 文件编辑
    • 整体概述
    • 协同文档权限设计
    • 协同文件保存与更新机制
    • 协同文件复制与删除
  • 05. 文件导入导出
    • 整体概述
    • 常见问题处理
  • 06. 石墨前端 API
    • 整体概述
    • 公共 API
      • 公共处理方法
      • 顶部栏定制 HeaderBars
    • 编辑器 API
      • 轻文档
      • 传统文档
      • 表格
      • 幻灯片
      • 表单
      • 应用表格
  • 07. 石墨后端 API
    • 整体概述
    • 错误码说明
    • 文件-预览 API
      • 访问预览文件
      • 创建文件预览缓存
    • 文件-协同编辑文件管理 API
      • 访问协同编辑文件
      • 创建协同文件
      • 创建协同文件副本
      • 删除协同文件
    • 文件-导入导出 API
      • 文件导入
        • 文件导入说明
        • 创建导入任务
        • 获取导入进度
        • 创建导入任务(旧版)
        • 获取导入进度(旧版)
      • 文件导出
        • 文件导出流程
        • 创建导出任务
        • 获取导出进度
    • 文件-表格文件(Excel) API
      • 表格接口参数说明
      • 获取表格内容
      • 获取表格中的评论数
      • 更新表格内容
      • 追加表格内容
      • 删除表格行
      • 新增表格工作表
    • 文件-文稿文件(Word) API
      • 文稿书签说明
      • 读取文稿书签内容
      • 替换文稿书签内容
    • 文件-文档文件(类 Markdown) API
      • 获取文档中的评论列表
    • 文件-应用表格文件(多维表格)API
      • 应用表格列及单元格值结构
      • 应用表格接口调用规则
      • 获取数据表列表
      • 创建数据表
      • 获取字段列表
      • 创建字段
      • 更新字段
      • 删除字段
      • 新增行
      • 获取单行
      • 更新行
      • 删除行
    • 文件-获取额外信息 API
      • 获取文件的纯文本内容
      • 文件纯文本字数统计
      • 获取文件的历史列表
      • 获取文件的版本列表
      • 获取文件内容中所有的 @ 人信息列表
      • 还原文件历史版本
    • 系统管理 API
      • 应用管理
        • 获取应用详情
        • 更新应用回调地址
      • 用户席位管理
        • 用户席位状态说明
        • 获取用户列表和席位状态
        • 激活用户席位​
        • 取消用户席位​
        • 批量设置用户席位
    • 其他 API
      • 上报事件
      • 创建行为历史
      • 推送文件内全部的用户
      • 推送用户全部的 websocket 连接
    • 获取行列表
  • 08. 回调接口(你的应用需实现的接口)
    • 整体概述
    • 文件信息
      • 文件权限说明
      • [重要] 获取文件元信息-协同文档
      • [重要] 获取文件元信息-预览文档
      • 获取当前用户的文件列表
      • 获取文件的协作者列表
      • 获取接入方指定文件的完整访问地址
      • 获取文件元信息-协同文档自动任务(admin)
      • 根据指定用户获取文件元信息-协同文档(admin)
    • 用户信息
      • 批量获取用户信息(admin)
      • [重要] 获取当前用户信息
      • 获取当前用户所在团队信息
      • 获取指定用户信息
      • 获取用户水印信息
      • 获取用户部门路径
      • 批量获取用户信息
    • 团队和部门
      • 特殊部门 ID 说明
      • 获取团队下的成员列表
      • 获取部门信息
      • 获取部门的下级部门节点
      • 获取部门下的成员分页列表
    • 搜索功能
      • 获取与文件相关的用户列表
      • 获取与文件相关的文件列表
      • 按关键字搜索文件和用户列表
    • 事件推送
      • 整体概述
      • 评论(Comment)
        • 轻文档
          • 添加评论
          • 删除评论
          • 结束评论
          • 对于评论的回复评论
        • 表格
          • 添加评论
          • 删除评论
          • 结束评论
          • 对于评论的回复评论
        • 传统文档
          • 对于评论的回复评论
          • 添加评论
          • 更新评论
          • 删除评论
        • 幻灯片
          • 添加评论
          • 删除评论
          • 结束评论
          • 对于评论的回复评论
        • 应用表格
          • 添加评论
          • 对于评论的回复评论
          • 删除评论
      • 讨论(Discussion)
        • 轻文档
          • 发送讨论消息
      • 提及(MentionAt @ 人)
        • 轻文档
          • 在评论中 at
          • 在讨论中 at
          • 在正文中 at
        • 表格
          • 在评论中 at
          • 在正文中 at
        • 传统文档
          • 在评论中 at
          • 在正文中 at
        • 应用表格
          • 在评论中 at
          • 在正文中 at
      • 日期提醒 (DateMention)
        • 轻文档
          • 创建
          • 修改
          • 删除
        • 表格
          • 创建
          • 修改
          • 删除
        • 传统文档
          • 创建
          • 修改
          • 删除
      • 文件内容更新 (FileContent)
        • 文件内容更新
      • 文档协作者协同状态变化 (Collaborator)
        • 文档协作者协同状态变化
      • 文件版本 (Revision)
        • 版本
      • 系统事件 (System)
        • 系统事件
      • 回调请求错误(实验性)
        • 回调请求错误
  • 09. 核心模型
    • 你的应用如何设计应用(app)模型?
    • 你的应用如何设计文件数据模型?
    • 你的应用如何设计通讯录模型?
    • 你的应用系统如何设计文件权限模型?
  • 10. 典型场景方案
    • 云盘场景
    • IM 场景
    • 示例代码仓库
  • 11. 常见问题
    • 访问接口提示 Signature
    • 文件预览或导入报错
    • 首次接入 SDK 报错
    • 文档预览如何做防盗链
    • 复制粘贴、全屏操作不正常
    • 如何实现文档模板功能
    • 文档内容何时保存
    • 移动端不支持 blob 协议导致预览失败
    • 如何实现文件重命名
    • 如何通过接口修改文档内容
    • @人员时如何直接跳转至对应锚点
  1. 02. 鉴权与安全

签名凭证 Signature

Signature 是你的应用接入身份的凭证。它由 appId + appSecret 派生,最常被石墨用来校验"这次请求确实来自你的应用";在石墨主动通知你的应用的场景里,它也是你的应用反向验真的唯一线索。

一、用途与使用场景#

Signature 出现在两条链路上,方向相反、校验侧不同:
要点:
Signature 不携带业务信息,里面只有"我是谁(kid)+ 什么时候过期(exp)+ 必要时的 scope / fileId"。业务上下文请放进 Token。
Signature 是短期凭证。过期时间越长,泄露后的爆炸半径越大;建议默认几分钟到 10 分钟内。注意:部分高敏感接口要求 exp ≤ 5 分钟。
appSecret 永远不离开你的应用后端:不进前端、不进 App、不写日志、不进静态配置、不进代码仓库。

二、JWT 结构#

Signature 是一个标准 JWT,三段式:
Header . Payload . Signature
xxxxx  . yyyyy   . zzzzz

2.1 Header#

JWT 的元数据,kid 必填——它就是你的 appId,石墨用它定位用哪把 appSecret 校验。
{
  "alg": "HS256",
  "typ": "JWT",
  "kid": "your_app_id"
}

2.2 Payload#

业务字段:
{
  "exp": 1612411882,
  "scope": "license",
  "fileId": "file_123"
}
参数类型必填说明
expnumber是过期时间,秒级时间戳。校验逻辑:当前秒 < exp 才有效
scopestring否接口访问范围。调用 license / 系统管理类接口时必须带 "license"
fileIdstring否文件标识。仅 /admin 类接口需要,用来把签名作用范围限定到单文件

2.3 关键约束#

算法固定 HS256。不要尝试 RS256 / ES256,否者会导致石墨侧无法解析。
exp 一定要"秒"。是 JWT 标准里默认的单位。
kid 必须落在 Header,不要塞到 Payload。
服务器时钟必须准。exp 校验对偏差敏感,建议所有节点跑 NTP,控制偏差在 ±2 分钟内。

三、生成方式#

3.1 代码示例#

下面给出 Java / Go / Python 三种语言的最小示例,均基于 HS256。生产环境请把 appSecret 从配置中心 / KMS 读取,不要硬编码。
Java
Go
Python
依赖(参考 auth0/java-jwt):
<dependency>
  <groupId>com.auth0</groupId>
  <artifactId>java-jwt</artifactId>
  <version>4.4.0</version>
</dependency>

3.2 在线生成与校验工具#

石墨提供了一个纯前端的 Signature 生成 / 校验工具,可直接用于联调:
该工具为纯前端实现,不会将你的 appId / appSecret 上传到任何服务器。如对安全性要求更高,可拉源码本地跑:
GitHub
https://github.com/shimo-open/shimo-sdk-signature-tool
Gitee
https://gitee.com/luyang950/shimo-sdk-signature-tool

四、Signature 的校验#

校验侧(石墨或你的应用,取决于方向)拿到 Signature 后必须经过如下流程校验:
要点:
kid → secret 的映射要做。多 App 共用一个回调入口时,先按 kid 找到对应的 appSecret,再算 HMAC,否则没法分辨同一个 endpoint 上不同应用的请求。
exp 校验允许小幅容差。建议 ±2 分钟,覆盖正常的 NTP 抖动;超出直接 401。
scope 与接口要求要对得上。例如 /admin/* 类接口必须带 scope=license,否则 403。
失败统一返回 4xx,鉴权失败用 401,业务拒绝用 403。返回 200 会让石墨认定送达,事件丢失;返回 5xx 会触发无意义重试。
Signature 是一次性消费。即使没过期也不要拿同一个 Signature 反复打多个接口。否规则会导致风险面扩大。
在主动通知场景,校验侧是你的应用。详见 签名凭证:Signature 与 Token § 回调接口的鉴权实现。

五、排查清单#

Signature 出错时返回的状态码通常是 401 / 403,错误信息里常出现 signature / kid / exp。按顺序排查:
现象检查点修复方向
错误信息提示 kid invalid 或"应用不存在"Header 是否包含 kid=AppIdappId 写入 Header 的 kid,不要塞 Payload
错误信息提示 signature mismatchHMAC 计算 / Base64URL 编码是否标准用 appSecret 做 HMAC-SHA256,再 Base64URL,拼成 header.payload.signature;不要二次拼接或转义
错误信息提示 exp expiredexp 单位 / 服务器时间必须秒级时间戳;所有节点跑 NTP;偏差控制 ±2 分钟
401 / 403 但本地用 生成工具 可通过环境配置确认线上配置的 appId / appSecret 与请求一致,避免测试 / 生产串包
调用 /admin 或 /license 类接口被拒缺 scope / fileId这类接口必须显式带 scope=license,部分接口还要带 fileId
主动通知场景的回调验签失败是否按 X-WebOffice-Credential-Type: 3 分支走"仅 Signature"校验同一回调 endpoint 要支持两种入站方式,详见 签名凭证:Signature 与 Token § 回调接口的鉴权实现

六、常见误区#

误区实际影响正确做法
前端持有 appSecret、本地签 Signature一旦泄露整个接入身份被人冒用,且不可吊销Signature 一律后端签发,前端只拿结果
exp 写成毫秒级表面通过校验,但语义上等于"几十年后",部分网关会直接拦截严格秒级 (time.Now().Unix() / int(time.time()))
exp 设得很长(小时 / 天级)一次泄露长时间可用,等于实质上无防护默认几分钟,严格接口 ≤ 5 分钟
同一个 Signature 在前端被复用打多个接口一旦窗口过期后续请求全部失败每次会话取一次新的 signature + token
使用其他算法(RS256 / ES256 / none)石墨直接 401固定 HS256
kid 放进 Payload 而非 Header石墨找不到应用 → 401kid 必须落在 Header
appSecret 提交到代码仓库一次泄露永久泄露,且各分支都被污染用 KMS / Vault / 环境变量;CI 跑秘密扫描
调用 /license 接口忘了 scope=license403严格按接口文档加 scope,并把 exp 缩到 ≤ 4 分钟
多节点服务器时钟未同步偶发合法请求被判过期 / 重放所有节点跑 NTP;签发 / 校验都允许 ±2 分钟容差
把 Signature 当业务幂等键Signature 每次都不一样,根本不可比对业务幂等键独立维护(事件 id / 任务 id)
修改于 2026-06-22 02:43:30
上一页
签名凭证 Token
下一页
整体概述
Built with