各位分享一下登录验证码的实现细节?

2020-12-20 08:33:38 +08:00
 black11black
如题,关于登录验证,之前发过一个帖子,询问前端验证码是否有意义,当时问那个问题有两个考虑,其一是我不了解 js 模块经过混淆后在生产级别的安全性,其二是我觉得后端生成验证码的话理论上可以成为饱和攻击对象,基本靠部署引擎拦截,跟业务无关了。(因为我没有被这么攻击过,纯粹是猜想)

当时回帖里诸位认为前端验证码搞不起,我也就放弃了。

这个贴想问一下各位的验证码细节上都是怎么实现的,因为想要无状态部署,各位看看我现在的方案行不行。我现在用的方案是后端生成验证码的同时生成 hash 作为令牌,与验证码图片一同发送至前端。(比如一个简单的算法,将随机生成的验证码重复一次再经过 sha1),而前端进行验证码检验的时候,通过验算决定是否放行。

感觉理论上只要 hash 算法保密应该这套系统就是安全的?
3041 次点击
所在节点    问与答
26 条回复
sampeng
2020-12-20 09:29:01 +08:00
验证在服务端进行,客户端只是体验
eason1874
2020-12-20 09:29:32 +08:00
无状态,加盐加时间戳能防破解,但是在有效期内有重放问题,适合的场景不多。
lpts007
2020-12-20 09:29:37 +08:00
“而前端进行验证码检验的时候,通过验算决定是否放行。”

这意思还是前端判断是否正确?
imdong
2020-12-20 09:36:19 +08:00
方案一(常见)
将验证码存于用户 Session 之中(具体方法有很多),验证后删除。

方案二(和你的做法相似)
生成的验证码进行加密或不可逆哈希(应该加盐防止彩虹表攻击),然后应该绑定一个时间与唯一 ID,如一分钟内有效,验证成功后将唯一 ID 存起来,一分钟内不允许使用,防止重放攻击。
jzmws
2020-12-20 09:58:45 +08:00
@imdong 相对来说第二种更好一些, 0202 年基于 session 认证有很多坑, 前后端跨域在 chrome 80 以上同步不到 session

配合配合 redis 就很方便了 ,不用去管理验证码失效的问题
1. 获取验证 把图片显示给前端的同时,并且带上当前验证码存储的 key 值
2.前端提交时候 用验证码的 key 值和输入内容
3.通过 key 去取 redis 中内容和输入比较
gam2046
2020-12-20 11:52:42 +08:00
前端是不可信的,任何在客户端运行的代码都不可信,服务端不能假定任何输入数据是没有被篡改过的。

因此如果是前端通过某种离线算法验证,那么整套验证机制就形同虚设了。未经授权的访问都可以通过相同的路径访问,因为服务端无法区分。
westoy
2020-12-20 12:07:28 +08:00
哪有啥真正的无状态啊, 你就算用 secure cookie 做 session, 用户改个密码要多个设备同步登出不还得服务端保存一个 token 做检验嘛
johnsona
2020-12-20 15:36:25 +08:00
@westoy 我之前总监就被网上博客忽悠瘸了,要什么无状态,自己也说不清楚,服务端不存状态的话,很多业务场景没办法给他做
Lonely
2020-12-20 17:36:31 +08:00
@johnsona 状态存到其他地方罢了,服务本身不存状态
wellsc
2020-12-20 17:38:47 +08:00
@johnsona 搞个分布式 session 之类的东西,业务容器本身还是无状态的,你们总监自己没理解罢了
black11black
2020-12-20 21:34:12 +08:00
@lpts007 表述错误,意思是前端发送这个请求时,(后端)完成检验
black11black
2020-12-20 21:37:53 +08:00
@johnsona 这有啥说不清楚的,当然要无状态,要不然服务可用性怎么拉上去?
johnsona
2020-12-20 21:42:13 +08:00
@black11black 不是说你这个业务,我是说有的业务,比如有的人说 jwt 好,不用存后端,无状态,验证签名就好了,还可以存数据,不会被窜改,可以横向扩展,那退出登录怎么做,revoke jwt 还是要加一个黑名单,这就有的人乱搞的无状态
johnsona
2020-12-20 21:43:00 +08:00
@wellsc 我的主张一直都是分布式 session
black11black
2020-12-20 21:45:48 +08:00
@johnsona jwt 退出登录确实不好解决,不过本身不会引起安全问题,我认为可以干脆不做这块。

@imdong 所以看来为了防止重放,无论如何还是要保存一个节点间同步状态。因为理论上希望系统部署越简单越好,能只用 sql 就不多加服务,看来是不行了。
black11black
2020-12-20 21:48:15 +08:00
@johnsona 分布式 session 具体实现上怎么操作?维护一个进程间通信协议?或者 nginx 绑定 ip ?
wellsc
2020-12-20 22:06:26 +08:00
@black11black 可以用 redis 实现,和缓存差不多道理的
johnsona
2020-12-20 22:35:54 +08:00
@black11black 百度
johnsona
2020-12-20 22:36:43 +08:00
@black11black 感觉你想的太复杂或者可能受 tomcat 影响吗
johnsona
2020-12-20 22:58:36 +08:00
@black11black 你怎么跟产品解释说不做退出登陆,产品会觉得这么简单的功能

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

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

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

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

© 2021 V2EX