各位分享一下登录验证码的实现细节? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
black11black

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

  •  
  •   black11black 2020 年 12 月 20 日 via Android 3243 次点击
    这是一个创建于 1951 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如题,关于登录验证,之前发过一个帖子,询问前端验证码是否有意义,当时问那个问题有两个考虑,其一是我不了解 js 模块经过混淆后在生产级别的安全性,其二是我觉得后端生成验证码的话理论上可以成为饱和攻击对象,基本靠部署引擎拦截,跟业务无关了。(因为我没有被这么攻击过,纯粹是猜想)

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

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

    感觉理论上只要 hash 算法保密应该这套系统就是安全的?
    26 条回复    2020-12-22 08:51:56 +08:00
    sampeng
        1
    sampeng  
       2020 年 12 月 20 日 via iPhone
    验证在服务端进行,客户端只是体验
    eason1874
        2
    eason1874  
       2020 年 12 月 20 日
    无状态,加盐加时间戳能防破解,但是在有效期内有重放问题,适合的场景不多。
    lpts007
        3
    lpts007  
       2020 年 12 月 20 日 via Android
    “而前端进行验证码检验的时候,通过验算决定是否放行。”

    这意思还是前端判断是否正确?
    imdong
        4
    imdong  
       2020 年 12 月 20 日 via iPhone
    方案一(常见)
    将验证码存于用户 Session 之中(具体方法有很多),验证后删除。

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

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

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

    @imdong 所以看来为了防止重放,无论如何还是要保存一个节点间同步状态。因为理论上希望系统部署越简单越好,能只用 sql 就不多加服务,看来是不行了。
    black11black
        16
    black11black  
    OP
       2020 年 12 月 20 日 via Android
    @johnsona 分布式 session 具体实现上怎么操作?维护一个进程间通信协议?或者 nginx 绑定 ip ?
    wellsc
        17
    wellsc  
       2020 年 12 月 20 日
    @black11black 可以用 redis 实现,和缓存差不多道理的
    johnsona
        18
    johnsona  
       2020 年 12 月 20 日 via iPhone
    @black11black 百度
    johnsona
        19
    johnsona  
       2020 年 12 月 20 日 via iPhone
    @black11black 感觉你想的太复杂或者可能受 tomcat 影响吗
    johnsona
        20
    johnsona  
       2020 年 12 月 20 日 via iPhone
    @black11black 你怎么跟产品解释说不做退出登陆,产品会觉得这么简单的功能
    Oceanhime
        21
    Oceanhime  
       2020 年 12 月 20 日
    可以看看 vcaptcha 的离线验证方案, 和你的意思感觉差不多?
    https://www.vaptcha.com/document/faq.html#%E7%A6%BB%E7%BA%BF%E9%AA%8C%E8%AF%81%E6%A8%A1%E5%BC%8F%E5%8E%9F%E7%90%86
    非利益相关
    black11black
        22
    black11black  
    OP
       2020 年 12 月 21 日 via Android
    @johnsona 不不,退出当然可以做,我的意思是即使后端没法验证退出,实际上倒不构成安全问题
    ysc3839
        23
    ysc3839  
       2020 年 12 月 21 日 via Android
    我最近也有类似需求,最终选择的方案是 Encrypted JWT,有效期设为 2 分钟,使用后加到缓存中避免重放攻击。

    登录后也是返回 JWT,退出登录的话是禁止多处登录,然后数据库里面存一个 token valid since 时间戳,每次登录或者退出登录直接更新这个。
    johnsona
        24
    johnsona  
       2020 年 12 月 21 日 via iPhone
    @black11black 我当时就这么搞的,我让前段退出直接删除 token 就行了,我不要面子的吗?他们不懂还以为我不行,而且前段删除 token,这个 token 还没 revoke 呢
    black11black
        25
    black11black  
    OP
       2020 年 12 月 22 日
    @ysc3839 token valid since 是指维护一个进程间共享缓存,退出登录以后把这个 token 设为 invalid ?
    ysc3839
        26
    ysc3839  
       2020 年 12 月 22 日 via Android
    @black11black 只是存时间戳,在此时间戳之前签发的 token 都无效。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1484 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 60ms UTC 17:04 PVG 01:04 LAX 10:04 JFK 13:04
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86