Vue项目接口防刷加固:接入腾讯云天御验证码实现人机验证、恶意请求拦截
本文最后更新于 2025年9月12日 下午
我们在设计公共业务接口的时候(e.g. 登录、公共 API 请求等),为了防止恶意请求,我们通常会采用人机验证、恶意请求拦截等手段来保护我们的接口。本文将在 Vue3 项目基础上介绍如何使用腾讯云天御验证码来实现人机验证和恶意请求拦截。
人机验证
网站的数据通常都是列表、分页展示,存在一定的规律,比如 WordPress 的评论列表,每页显示 10 条,每次的翻页就是通过 API 接口提取数据库的数据进行展示。 如果没有人机验证或者恶意请求的拦截,那么攻击者就可以通过爬虫程序,模拟用户行为,不断发起请求,获取数据,从而造成数据泄露、服务器负载过高、带宽消耗过大等问题。
除了后台 API 限制请求频率这种“保守防御”,我们可以采用一些更“精巧”的方式。比如本文介绍的验证码,通过人机验证,可以有效地防止爬虫程序的恶意请求。
人机验证码
验证码服务,其实形式很多。早些年登录 QQ 时候,弹出的“请输入图形中的数字/字母”就是一种验证码服务。原理就是通过随机生成一张图片,图片中包含一些数字或字母,让用户输入,如果输入正确,则允许登录,否则拒绝登录。
flowchart LR
A[👤 用户访问] --> B[🎲 生成验证码]
B --> C[📤 提交验证]
C --> D{🔍 校验结果}
D -->|✅ 成功| E[🎉 通过验证]
D -->|❌ 失败| B
style A fill:#e3f2fd,stroke:#1976d2
style B fill:#fff3e0,stroke:#f57c00
style E fill:#e8f5e8,stroke:#388e3c
输入图形数字这种形式已经很少了,随着样本数据和计算能力的提升,图形数字能拦截的基本只有“真人”。现在更流行的是滑动验证码、点选验证码、语音验证码等。比如: 我们这次介绍的腾讯云天御验证码。
滑动验证码
滑动验证码,顾名思义,就是需要用户拖动滑块,使滑块与缺口对齐,才能通过验证。这种验证码形式,判断用户能否把滑块对齐缺口只是验证的第一步;在验证的过程中,还会判定用户的滑动轨迹是否正常、Cookies是否异常等,只有全部通过,才会认为用户是真人,从而放行。
同时,相比以前传统的后端传图验证码,滑动验证码通常前台验证后,生成票据;后端接口可以校验票据是否有效,从而减少后端压力。类似于 JWT 这种模式。
天御验证码
我们这次就以天御验证码为例,介绍如何接入人机验证和恶意请求拦截。腾讯云天御验证码的官网地址是:
使用的场景一般在网站、APP、小程序等场景,看到官方有 React 的接入指南,但是没有 Vue,其实原理差不多,这次我们自己封转一个 Vue 组。
原理是前端请求验证码的接口,用户完成验证后,返回票据;之后前端携带票据到后端验证票据是否有效:
sequenceDiagram
participant U as 👤 用户
participant F as 🌐 前端
participant C as 🛡️ 验证码服务
participant B as 🔐 后端
U->>F: 访问页面
F->>C: 请求验证码
C->>F: 返回滑块验证
U->>F: 完成验证
F->>C: 提交结果
alt 验证成功
C->>F: 返回票据 🎫
F->>B: 携带票据请求
B->>C: 校验票据
C->>B: 验证结果
B->>F: 返回数据 ✅
else 验证失败
C->>F: 验证失败 ❌
F->>U: 重新验证
end
使用体验
在教程正式开始之际,我们来看一下最后的接入效果 🤔?
可以在 薄荷文档 上的 AI 功能进行提问,会自动触发验证码,如下图所示:
我们通过验证后,把前端会把生成的票据作为参数传递给后端,后端验证票据的有效性决定是否放行:
当然,你也可以在腾讯云的控制台上,切换验证码的样式、风控等级等:
操作前提
基础的网站开发知识,以及 Vue 的基础使用,这里不做赘述。完整的验证码业务,前端请求腾讯云验证码的接口来获取票据,后端接收票据,校验票据的有效性。
本次的操作,我前端就是使用 Vue3,后端就是用的 Golang。
当然,我们需要先开通腾讯云天御验证码的服务,新用户有 2w 次的免费额度,足够我们测试了:
Vue 前端接入
前端的接入,我们可以参考官方的 Web 客户端接入和 React 版本接入Demo 来完成 Vue 的实现。
首先是定义容器,我们创建一个 component 组件,用来承载验证码的组件,并创建一个容器,用来后续的验证码挂载:
1 |
|
添加的 props
接受父组件参数。其中:
appId
是天御验证码的 CaptchaAppId;enabled
表示是否启用验证码,默认为true
;show
表示是否显示验证码,默认为false
;statusText
表示验证码状态文案,默认为请完成安全验证...
;containerId
验证码容器的 ID,默认为captcha-embed
;为我们使用验证码的嵌入模式时候,进行替换展示的容器 ID(天御验证码有两种模式,一种是嵌入模式,一种是弹窗模式)。
之后的验证,关键代码自然是触发emit
内的success
事件,传递票据和随机字符串到上级父组件。
1 |
|
我们在父组件中监听 success
事件,把票据和随机字符串传递给后端,从而决定是否响应这次请求:
1 |
|
完整的代码可以参考:
我们总结一下 Vue 前端接入的完整流程:
flowchart LR
A[🚀 开通服务获取AppId] --> B[⚡ Vue组件]
B --> C{📱 启用验证?}
C -->|否| D[⏭️ 跳过验证]
C -->|是| E[🎯 加载验证码]
E --> F{👆 用户操作}
F -->|✅ 成功| G[🎫 传递票据到后端]
F -->|❌ 失败| E
G --> H[✨ 后端校验]
D --> H
%% 样式定义
style A fill:#4fc3f7,stroke:#0288d1,stroke-width:3px,color:#fff,font-weight:bold
style B fill:#81c784,stroke:#388e3c,stroke-width:2px,color:#fff,font-weight:bold
style C fill:#ffb74d,stroke:#f57c00,stroke-width:2px,color:#fff,font-weight:bold
style D fill:#a1887f,stroke:#5d4037,stroke-width:2px,color:#fff
style E fill:#f06292,stroke:#c2185b,stroke-width:2px,color:#fff,font-weight:bold
style F fill:#ba68c8,stroke:#7b1fa2,stroke-width:2px,color:#fff,font-weight:bold
style G fill:#4db6ac,stroke:#00695c,stroke-width:2px,color:#fff,font-weight:bold
style H fill:#ff8a65,stroke:#d84315,stroke-width:2px,color:#fff,font-weight:bold
%% 连接线样式
linkStyle 0 stroke:#0288d1,stroke-width:3px
linkStyle 1 stroke:#388e3c,stroke-width:2px
linkStyle 2 stroke:#f57c00,stroke-width:2px
linkStyle 3 stroke:#c2185b,stroke-width:2px
linkStyle 4 stroke:#7b1fa2,stroke-width:2px
linkStyle 5 stroke:#00695c,stroke-width:2px
linkStyle 6 stroke:#c2185b,stroke-width:2px,stroke-dasharray: 5 5
linkStyle 7 stroke:#2e7d32,stroke-width:3px
linkStyle 8 stroke:#5d4037,stroke-width:2px,stroke-dasharray: 3 3
当然,只是解决了前端接入,还需要后端配合,才能真正实现验证功能。接下来就看看后端怎么校验票据有效性。
Go 后端校验
后端的接入,官方的文档直接指引我们到 API Explorer 进行在线调试和代码生成。
在调用成功以后,有一个基础的代码生成供我们进行自己的业务改造:
比如我们的适配,首先是定义一个结构体读取我们的腾讯云 SecretId、SecretKey 和 验证码 CaptchaAppId 等配置:
1 |
|
然后就是初始化时候读取配置文件:
1 |
|
在请求体内添加ticket
和randstr
字段的映射(CaptchaTicket 和 CaptchaRandstr):
1 |
|
在控制层,也就是接口处理函数中,我们就可以通过CaptchaTicket
和CaptchaRandstr
获取到票据和随机字符串,然后调用腾讯云的接口进行校验:
1 |
|
总体来说,还是很简单的。联动一下前端,整个流程就是:
sequenceDiagram
participant U as 👤 用户
participant V as 🟢 Vue前端
participant T as 🛡️ 腾讯云服务
participant G as 🔵 Go后端
Note over U,G: 完整的验证码集成流程
U->>V: 1. 访问页面/触发验证
V->>V: 2. 检查是否启用验证码
alt 启用验证码
V->>T: 3. 加载验证码组件
T->>V: 4. 返回滑块验证界面
V->>U: 5. 展示验证码
U->>T: 6. 完成滑块验证
T->>V: 7. 返回票据(ticket+randstr)
V->>G: 8. 发送请求(携带票据)
Note right of V: 请求体包含:<br/>- Query: 用户输入<br/>- CaptchaTicket: 验证票据<br/>- CaptchaRandstr: 随机字符串
G->>G: 9. 解析请求参数
G->>T: 10. 调用DescribeCaptchaResult API
Note right of G: 验证参数:<br/>- CaptchaAppId<br/>- Ticket<br/>- Randstr<br/>- UserIP
T->>G: 11. 返回验证结果
alt 验证成功(Code=1)
G->>V: 12. 处理业务逻辑并返回结果 ✅
V->>U: 13. 展示成功结果
else 验证失败
G->>V: 14. 返回验证失败错误 ❌
V->>U: 15. 提示重新验证
end
else 跳过验证码
V->>G: 直接发送请求
G->>V: 处理业务逻辑
V->>U: 返回结果
end
完整的代码可以参考:
未来期待
其实,我个人也有用过其他的验证码,比如: Geetest(极验)和Google reCAPTCHA。
个人觉得腾讯云天御验证码的接入还是比较方便的,尤其是 API Explorer 的在线调试和代码生成,还是非常方便的。
但是在形式上,还是有些欠缺…… 没有看到 Geetest 那样的九宫格点选、五子棋验证等创意的交互形式。缺少了一些创新。在计费上,单次价格 0.005元/次,还是比较贵的(对于个人开发者而已🤔)。
END
好啦,今天就到这里了,感谢你的阅读,欢迎交流。
最后,如果你觉得本篇教程对你有帮助,欢迎加入我们的开发者交流群: 812198734 ,一起交流学习,共同进步。