mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
1442 字
4 分钟
飞书自动化后端验证防刷方案
2026-03-13

小舟工具箱 上月独立访客数达到了近 4000,这么多人了总得想个由头维持一下运营动力……咳咳,于是整了个市场分析的调研问卷,用的飞书多维表格。

为了提高参与率,在问卷结束后可以参与微信小程序抽奖,总价值 200 元,共 215 份。虽然每个人平分下来 1 块都不到,而且和微信号绑定每号只能参与一次,但我还是觉得有必要防范盗刷。

开始设计整体逻辑#

抽奖的小程序提供的参与条件非常丰富,可对我这种场景来说,第一眼只有限制分享有点用,其他的意义聊胜于无。

挨个展开看看,发现口令支持一次性口令,这就好办的多了!

只要让每份问卷填完后拿一个专属口令,就可以最大程度上避免盗刷了🤓☝️

image.webp

飞书问卷的功能限制#

但是,飞书问卷没有什么题目变量设置,抽奖功能也仅仅支持个标题、图片、联系方式,甚至兑换码这种功能都没有,该怎么实现呢?不能是留邮箱挨个手动发吧?

image.webp
问卷抽奖奖品设置页

好在「提交问卷后」支持配置跳转链接,这意味着我们可以跳转到一个获取口令的网页,拿到口令后再前往小程序抽奖,流程上算是能跑通。

image.webp

微信小程序跳转难题#

这里还有个难点,怎么从网页前往小程序?微信使用的是私有协议头 weixin://,虽然抽奖小程序告诉了我们 appID 和抽奖活动路径,但是微信不支持未授权的网站直接调用该协议…😰

相对靠谱的方法主要有两种:

  1. 在开放平台申请相关接口:但是还要备案、审核,即使这些都通过了,还有调用上限,流程比较长。
  2. 公众号文章中嵌入小程序卡片:公众号文章支持浏览器直接打开,小程序卡片会引导进入微信,不过个人公众号认证需成年主体😶
  3. 使用已授权域名作为中转:当时查了半个多小时,唯一找到稍微靠谱点的是 C1N 的短链服务,不过需要注册。当时大半夜的,注册系统正在维护 (23:00~8:00),也只得作罢……(写这篇文章时才想起这茬,一看时间 23:41…)

最后直接用的抽奖小程序自带的分享链接,它会尝试使用 weixin:// 协议打开本地的微信,即使因为种种原因无法打开,也可以手动保存背景图在微信扫描其中的太阳码打开小程序。

另外还提供了文字版的指引,尽可能覆盖到不同的需求场景。

打开微信搜索「抽奖助手」小程序,进入首页口令并输入「xxxx」 即可参与抽奖。

身份验证 + 自动化#

然后,该怎么保证访问请求确实来自问卷提交后呢?最初我想的是检查一下 Referer 就够了,多的也实现不了。

不过,偶然想起之前在哪看过的一篇文章 (好像是卡兹克的?) 讲的是多维表格在自动化工作流中的应用,依稀记得文中所描绘之强大,我抱着试试的心态打开了自动化页面……

居然支持发送 HTTP 请求!而且完全没有限制!并且支持将用户填到问卷中的内容作为变量,你甚至可以把整份问卷结果发出去。

image.webp
飞书自动化支持 HTTP 请求
image.webp
问卷变量可作为参数传递
image.webp
包含变量的请求体示例

我们只需要在问卷内专门留一道能验证身份的题就可以了,比如我这里的输入 6 位数字 (由于飞书只能限制整数类型无法限制长度,所以虽说写的是 6 位,前后端都没限制 6 位以上的)。


完整梳理#

前面其实已经完全讲完了,剩下的无非就是后端接收处理,非常基础,AI 含量 100%,我只负责了逻辑验证和调试。

那 6 位数字下文简称为 Token

逻辑流程#

graph TD A[开始] --> B[问卷提交] B --> C[飞书调用 API 提交 Token] C --> D[后端将 Token 记录到数据库] D --> E subgraph E [前端流程] E1[跳转口令获取网页] --> E2[输入 Token 验证] E2 --> E3{调用 API 验证 Token 有效性} E3 -->|有效 | E4[返回口令] E3 -->|无效 | E5[返回错误] E4 --> E6[前端 Cookie 记录,同时渲染对应页面] E5 --> E7[前端处理错误类型,显示对应提示] E6 --> E8[结束] E7 --> E8 end

后端流程#

flowchart TD A[访问开始] --> B{检查 Referer 是否为飞书域名} B -->|否或为空 | C[返回 403] B -->|是 | D{检查本地是否有口令 Cookie(其实这个应当在referer之前)} D -->|是 | E[显示口令] D -->|否 | F[弹出模态框要求输入 Token] F --> K[点击验证按钮] K --> L[调用获取口令 API] L --> M{检查是否达到短时间内的限流阈值?} M -->|是 | N[返回 429] M -->|否 | O{验证 Token 是否在数据库中?} O -->|否 | P[返回错误并记录用户特征失败次数] P --> F O -->|是 | Q[从口令池中获取最靠前的一个口令] Q --> R[通过 API 返回口令] R --> S[将口令从口令池中删除] R --> T[前端收到后在本地存口令 Cookie] U[飞书问卷列表出现新提交] --> V{Token 栏是否为空?} V -->|是 | W[不处理] V -->|否 | X[调用 API 发送给后端服务器] X --> Y{验证是否为飞书特征?} Y -->|否 | Z[返回 444] Y -->|是 | AA[将 Token 存到数据库]

边界情况 & 总结#

看起来万无一失,但是,问卷一个人可以提交多份……如果要开启提交次数限制必须要启用登录,这无疑会大大降低填写率,所以我没这样做。

说白了都只是防君子和小聪明的,防重放攻击、api签名等等都没做,有些参数甚至是直接在 url 明文传输的awa

反正抽奖是和微信号绑定的,我不信会有人为了那几毛钱整一大批微信号来搞我,如果真有这种神人就给他了😅

另外,Cookie 这层验证对普通用户来说已经够用了,大部分人试一次发现需要验证,基本也就不会再折腾第二次,对问卷数据可靠性的影响其实很小。

而且口令要是被刷完了,手动再补一次就是。

当试错成本足够低时,竭力避错才是此时最高的成本。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

飞书自动化后端验证防刷方案
https://blog.lonzov.top/posts/feishu-antifraud/
作者
浪小舟
发布于
2026-03-13
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

封面
加载中…
正在加载中……
封面
加载中…
正在加载中……
0:00 / 0:00