有没有什么前端验证码的成熟方案?

2023-08-31 00:52:06 +08:00
 LeeReamond

首先,前端验证码和可靠二字完全不搭边我理解。但是后端验证码的话,后端首先需要进行一个 CPU 计算生成图片的过程,然后还需要维护一个对应状态,感觉成本有点高了,相比之下前端验证码对于后端来说就是无限轻量了。

有没有一种可能性是走两套方案,先前端再后端?比如注册验证这种场景,现在国内一般都是要调 API 发手机验证码的,为了保护 API 几乎都需要前置经过某种验证才能调用 API ,那么有没有可能,在前几次验证码时是前端验证,后端 API 根据用户 IP 或者什么其他信息维护一个屏蔽表,调用次数达到一定程度后再使用稍微安全一些的后端验证码这样?

这样前端的安全性要求其实也不高,能拦截 90%低端程序员就可以了。 有这样的项目吗?

3975 次点击
所在节点    程序员
37 条回复
yankebupt
2023-08-31 11:54:17 +08:00
比如那种定点滑块或者变异一点的二维滑块,客户端绘制,但是不是把验证结果发回去,而是把自己的绘制参数和用户的鼠标事件轨迹同时发回去服务器验证,用户就不知道验证逻辑是什么,而且为什么脚本自动滑有时候会失效。
geelaw
2023-08-31 11:55:27 +08:00
@yankebupt #16 经典计算机的对立面是量子计算机,这样说是因为利用量子计算可以让(发送给客户端的)程序只能(被客户端自行)运行一次,但经典计算机没有这种可能。

#18
>把明文的 Hash 也发过去让他自行验证。
我的解读是客户端会收到正确答案的 hash ,这样的话客户端可以自己尝试所有可能答案,计算它的 hash ,直到匹配为止,然后再把答案发给服务端。

>服务端只需算出他生成的那些张的 Hash ,而客户端需要枚举所有。而且等客户端枚举完,服务端可能以及换了一批 Hash 组合了
或者如果不在意服务端亲自 Hash 一下的话,可以每次给客户端随机的Hash组合算法用于验证……
比如
md5(sha1(salt(sha1(salt(md5())))))
salt(sha1(md5(sha1(salt(md5())))))

不太理解,客户端要想自己比对,当然需要知道如何计算 hash ,换用不同的算法没有意义。

In any case, 这个方案不好。此外,从攻防、补丁的角度思考效率也不高,应该从形式化和证明的角度思考。
libook
2023-08-31 11:56:26 +08:00
现在灰产,哪怕是低端程序员,Hack 接口是基操,前端验证码几乎没啥用,你只能防住完全不懂技术且也不会照着别人教程操作的人。从我们公司的经验来说,连小学生都知道怎么按照教程绕过限制薅羊毛。

除非你的产品需求非常明确就是防君子不防小人。
yankebupt
2023-08-31 11:57:40 +08:00
还有最新的Edge和Chrome免验证,由浏览器随时验证用户是否是真人,然后数字签名过去一个消息证明用户是真人,只要验证是Chrome的签名就行了。开源的Headless因为开源所以没证书也没签名,具体实现原理我也不清楚,可以参考下。
mdn
2023-08-31 12:01:02 +08:00
@libook 而且现在都是有人做好脚本,直接运行就好(比如抢票),只能防没有动手能力的小白
mdn
2023-08-31 12:04:35 +08:00
@yankebupt #24 Puppeteer 可以控制本地 chrome
yankebupt
2023-08-31 12:38:59 +08:00
@geelaw 形式化验证虽然不万能,讲个笑话,验证码:1+1=2,黑客:等等,那只是个猜想,还没有证明!不能形式化验证!但其实该用一样用……
但形式化验证也并不是完全没用,但凡客户端有台 Loseless qubit 量子电脑,最次也是租了点超算时间,那什么 hash 或者 salt 都没有用。有没有一定要客户端可以知道对错的实现呢?
有!

……
只是估计是有的。
我们把判断对错的任务交给用户,不交给计算机了。
考虑两个滑块,每个 5-6 张验证码,其中有两个是一样的,两个滑块图片风格不一样,都做成渐变视频,让用户把两个数字拉一样了,点提交……
判断只需两个滑块的位置阈值……
这样本地计算机就不知道验证码对错了,只有用户知道……
是不是形式化验证要的是这样的答案?我觉得是,但很可能用处不大……
yankebupt
2023-08-31 12:42:31 +08:00
附:知道对错是指用户能明确知道自己是否误输入,自愿承担多次误输入造成的封禁惩罚,知道看不清点刷新
如果明确的要拒掉错误输入的服务器请求,估计办不到的
mxT52CRuqR6o5
2023-08-31 12:43:44 +08:00
我建议直接把验证码去了,既不能阻挡机器人,又降低用户体验的东西为啥要做呢
yankebupt
2023-08-31 13:09:52 +08:00
@ mdn 被脚本或插件控制的时候不会发出签名信息
说的是因为浏览器验证用户是真人这段是闭源的。
主要因为大家有 Chromium 和 Webkit 是开源的的印象,这里是段闭源验证,套壳浏览器没有

当然可靠性没测过(没见人用过),所以不知道怎么样
zjsxwc
2023-08-31 13:11:22 +08:00
同意,后端验证码真没多少 cpu 成本,
比如 svg captcha ,
后端每个验证码的字母都预先生成 svg 文本,
要用的时候也不过改变一下这个字母扭曲的参数,
后端验证码的成本和输出 html 没有区别。

https://github.com/NikolaiT/SVG-Captcha
ganbuliao
2023-08-31 13:59:35 +08:00
用第三方的行为验证码
baobao1270
2023-08-31 15:45:03 +08:00
后端做风控+限频阿
LiuJiang
2023-08-31 17:06:33 +08:00
我也想问,有没有啥免费的验证服务,哈哈哈哈
loolac
2023-08-31 18:02:25 +08:00
手机扫码验证吧
vueli
2023-08-31 19:27:48 +08:00
后端可以返回验证码图片,几 KB
liuidetmks
2023-09-01 09:20:01 +08:00
能不能换个思路,使用,类似于比特币
你的请求的参数是 a ,找到随机 b 使得 sha256(a + b) 前面 20 个 bit 是 0 。(20 如果影响普通用户体验可以设置成 19 ,18)
b 作为 参数的签名 一起发送给服务器,服务器简单验证就行了


这样批量刷就变得很困难了
如果想继续增加刷 api 成本,可以使用 scrypt 这类消耗内存形 HASH 替代 sha256

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/969630

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX