V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kisshere
V2EX  ›  程序员

一个接口,浏览器每请求 100 次,弹出一次验证码,要求服务器端不记录浏览器对应 ip 的请求次数,该怎么实现?

  •  
  •   kisshere · 2019-12-27 09:11:19 +08:00 · 9031 次点击
    这是一个创建于 1799 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如果通过服务器端记录客户端对应 ip 的请求次数,数据库会撑爆的,如何从验证客户端浏览器提供的数据下手,让这个接口,浏览器每请求 100 次,就弹出一次验证码?

    $_COOKIE['requestCount']=$_COOKIE['requestCount']+1;
    if($_COOKIE['requestCount']>100){show_captcha();}//这种逻辑就算了哈,小学生都能修改 cookie 破解
    
    第 1 条附言  ·  2019-12-27 15:39:56 +08:00
    最终我还是采用简单粗暴的方法:rand(1,100)>98 && show_captcha();
    什么 cookie 加密和 Redis 和 memcache 存 ip 都弱爆了
    第 2 条附言  ·  2019-12-27 16:17:38 +08:00
    评论区提醒,random 的方式也不对,我还是老老实实用 Redis 记录 ip 递增访问次数吧
    89 条回复    2019-12-30 14:43:50 +08:00
    nianyu
        1
    nianyu  
       2019-12-27 09:16:02 +08:00
    你 又想安全 又要完全从客户端入手.办不到啊
    fancy111
        2
    fancy111  
       2019-12-27 09:17:07 +08:00
    你都说了验证客户端浏览器,那就 cookie 计数加密一下咯。
    或者 localStorage 什么的,反正存客户端嘛。
    但是有什么用?客户端随时可以清空的,你的计数不可能完全保存在客户端。
    kisshere
        3
    kisshere  
    OP
       2019-12-27 09:19:21 +08:00   ❤️ 1
    @fancy111 第一次请求就显示验证码,这个也可以接受,即用户清空 cookie,就显示验证码
    sagaxu
        4
    sagaxu  
       2019-12-27 09:19:47 +08:00 via Android   ❤️ 5
    random
    lhx2008
        5
    lhx2008  
       2019-12-27 09:20:20 +08:00 via Android
    数据库会存爆?每天清就行了,你想存爆挺难的。
    qinxg
        6
    qinxg  
       2019-12-27 09:21:08 +08:00
    放内存里啊
    phpdever
        7
    phpdever  
       2019-12-27 09:21:14 +08:00
    你的目的是防止客户端对接口滥用,解决思路应该是从后端角度处理

    怕数据库撑爆,可以用 Redis,简单点的,用计数器法就可以实现限流
    cominghome
        8
    cominghome  
       2019-12-27 09:21:16 +08:00
    如果通过服务器端记录客户端对应 ip 的请求次数,数据库会撑爆的

    1. 这个数据量,其实没你想的大
    2. 为什么要放数据库? memcached 不好用还是 redis 不香?
    kisshere
        9
    kisshere  
    OP
       2019-12-27 09:23:27 +08:00
    @cominghome
    @phpdever
    @lhx2008 用户用代理池来爬接口,数据库很可能冒烟
    annielong
        10
    annielong  
       2019-12-27 09:25:37 +08:00
    服务端返回数据的时候加一个 100 递减的参数,客户端请求数据时候必须带这个参数,
    virusdefender
        11
    virusdefender  
       2019-12-27 09:28:37 +08:00
    cookie 加密一下,虽然也不能根本性的解决这个问题
    zhenhuaYang
        12
    zhenhuaYang  
       2019-12-27 09:29:55 +08:00
    redis 的 incr 命令不香吗?
    lower
        13
    lower  
       2019-12-27 09:30:21 +08:00
    感觉你的 100 次限制,可能设置成在某个时间段里的限制,会不会好处理一些,比如是每天或者每个小时。
    服务端随便记录,时间一到,缓存自动失效或者定时清数据库。
    kisshere
        14
    kisshere  
    OP
       2019-12-27 09:30:55 +08:00
    @virusdefender cookie 可逆式加密也不能解决问题,用户每次携带同样的加密 cookie 给服务器端,服务器端每次都判断请求次数<100 而放行通过
    kisshere
        15
    kisshere  
    OP
       2019-12-27 09:32:57 +08:00
    @lower 我目前也是这么想的,只能通过失效时间上解决问题,而不能在请求次数上做文章,所以看看有没有 V 站大佬能通过客户端请求次数想个好办法
    lhx2008
        16
    lhx2008  
       2019-12-27 09:36:18 +08:00 via Android
    @kisshere 我说的数据库是内存数据库,冒不了烟,TPS 随便都是几万的,你如果不把 IP ban 掉,网站还早挂了
    zzzmh
        17
    zzzmh  
       2019-12-27 09:36:36 +08:00
    要么前端解决要么后端解决
    前端解决肯定不是绝对 100%安全,只能说相对来说压缩加密的 js 不容易调试和被改。推荐你了解一下 Fingerprintjs2
    后端用 nginx + lua 貌似可以,但我没写过类似的,只在论坛见过
    wwcxjun
        18
    wwcxjun  
       2019-12-27 09:44:41 +08:00
    Redis + 1,最简单的是使用 IP 作为 key,值就是请求次数, 判断值到一百就弹验证码,验证完了清空值就好了. Redis 不用考虑会撑爆了吧... 还是怕的话 可以加个失效时间
    chendy
        19
    chendy  
       2019-12-27 09:53:56 +08:00
    这种需求一定是服务端做,别人真想搞你的话客户端就是给人看接口的,不想搞你客户端做一堆防护也没用
    另外如果有必要的话就直接在业务上做限制,比如未登录用户只能看一点数据,登陆了可以看多一些,充值了随便看之类的
    alphatoad
        20
    alphatoad  
       2019-12-27 09:56:51 +08:00 via iPhone
    这个问题可以近似为弹出验证码的几率是 1%
    然后就不用说了吧(狗头
    catror
        21
    catror  
       2019-12-27 10:42:24 +08:00 via Android
    IP 请求次数放内存里就完事了,如果要多台服务器全局限制的话就用 redis。
    wml
        22
    wml  
       2019-12-27 10:48:48 +08:00
    @alphatoad 这样可能会导致用户体验不好 且想攻击重新请求一下就好了
    jiaming1992
        23
    jiaming1992  
       2019-12-27 11:06:06 +08:00
    可以给用户发个通知,让用户记录,每请求一次在本本上画一笔,等到 100 个时让用户通知你。
    zlhsvc
        24
    zlhsvc  
       2019-12-27 11:07:49 +08:00
    内存里就完事了,然后加个过期清理,你不可能永久记录这个次数吧
    forgottencoast
        25
    forgottencoast  
       2019-12-27 11:11:15 +08:00
    @kisshere #3 说的就可以啊,客户端 Cookie 加密,如果没有携带参数就出验证码,这样清理 Cookie 这招就没用了。
    Cookie 带 IP 地址,一换 IP 地址就弹验证码。
    kisshere
        26
    kisshere  
    OP
       2019-12-27 11:15:43 +08:00
    @forgottencoast 比如用户请求了 3 次,3 经过加密成为一个字符串 asdf,用户 F12 抓到这个 asdf 后,每次都携带这个字符串 asdf 给提交给服务器,服务器每次解密后得出是 3,然后放行通过。。。。。。
    snoopyxdy1
        27
    snoopyxdy1  
       2019-12-27 11:21:24 +08:00
    用 cookie 签名做就可以拉,第一次的话就无脑弹验证码
    noahsophie
        28
    noahsophie  
       2019-12-27 11:30:44 +08:00
    浏览器每请求 100 次,弹出一次验证码。这个就是防范普通用户的,所以前端怎么方便怎么来,其次服务端可以在网关层做处理,比如在 nginx 限制 IP 访问频率
    darknoll
        29
    darknoll  
       2019-12-27 11:33:03 +08:00
    nginx 不行么
    lihongjie0209
        30
    lihongjie0209  
       2019-12-27 11:33:20 +08:00
    Ip + counter 放内存不就行了?
    数据库会爆炸??? 全球的 IP 都会访问你们的接口?
    passerbytiny
        31
    passerbytiny  
       2019-12-27 11:38:25 +08:00   ❤️ 2
    首先,客户端 IP 不是浏览器能决定的,那是中间网络决定的,你后面提到用代理池怕接口,那应该是想到这一点了。

    然后,每请求 100 次弹出一次验证码这个逻辑不对,应该是:若短时间内连续请求 N 次,则接下来一段时间内必弹验证码,然后重置。一个 IP 的请求次数,并不是静态永久数据,而是动态瞬时数据,它的记录在首次请求的时候创建,在重置,或者超过监控时间的时候删除。(如果有心思,还可以考虑更花哨的重置和监控时机。)

    最后,记录客户端对应 ip 的请求次数,一个 IP 就一条记录,如果要达到数据库爆仓的效果,那得短时间内几千万个新 IP 访问服务器,这时候你首要考虑的就不是爆仓,而是 DDOS 了。

    所以,安心的记录吧,当然还是建议 Redis 记录,除了性能考虑外,你还可以不用做重置处理(由 redis 超时机制自动重置)
    Sunyanzi
        32
    Sunyanzi  
       2019-12-27 12:04:48 +08:00   ❤️ 2
    这需求能做 ... 不需要记录用户 IP ... 需要用户传四个元素 ... counter / nonce / timestamp / signature ...

    如果不严谨要求不能挨重放的话 nonce 也可以去掉 ... 这样服务端就不存任何东西了 ...

    不知道这种方式你能不能理解 ... 如果需要我可以写 DEMO ...
    zgq3337
        33
    zgq3337  
       2019-12-27 12:07:16 +08:00 via Android
    用服务器累加器,加解密,IP 当 ID
    bitholic
        34
    bitholic  
       2019-12-27 12:13:11 +08:00
    redis incr 很适用: https://redis.io/commands/INCR
    zoikhemlab
        35
    zoikhemlab  
       2019-12-27 12:56:40 +08:00
    @fancy111 第一次就弹验证码,然后加,加到一百清空。
    optional
        36
    optional  
       2019-12-27 13:01:40 +08:00
    服务端不存任何东西无法避免重放攻击,如果可以接受服务端存少量数据倒可以做的。
    aver4vex
        37
    aver4vex  
       2019-12-27 13:02:19 +08:00
    cookie 里计数呗,既然不想服务端计数,那就浏览器计数咯。
    wangxiaoaer
        38
    wangxiaoaer  
       2019-12-27 13:12:07 +08:00
    借楼问一下,假如接口正常返回的是二进制数据(比如 img 标签的图片地址),后台检测到频繁,准备前端弹验证码? 具体怎么弹? 在原本应该返回图片的这个接口返回验证码消息,然后前端配合处理界面显示? 这样感觉不合适啊。
    zchlwj
        39
    zchlwj  
       2019-12-27 14:03:14 +08:00
    干嘛放数据库,redis 不香吗? HyperLogLog、布隆选择器,实现的方式多的很。
    seakingii
        40
    seakingii  
       2019-12-27 14:04:04 +08:00
    肯定服务器计数啊,一个 IP 对应一个计数器,用 redis 或者自己写个使用内存存储计数的服务器,对付这种需求应该是压力很小啊.

    另外这种限制客户端请求的,也可以考虑回的方案,比如限制频率,比如一秒钟最多请求多少次,一分钟最多,一天最多来替代.这种解决方案可以使用 WEB SERVER 来解决,不用自己开发.
    zmqking
        41
    zmqking  
       2019-12-27 14:11:44 +08:00
    Fingerprint.js 了解下。
    mconvert
        42
    mconvert  
       2019-12-27 14:11:53 +08:00
    首先理解不了为啥会撑爆,第二就算存数据库不行,redis 存总也可以吧,key 是 ip,value 是 count
    no1xsyzy
        43
    no1xsyzy  
       2019-12-27 14:12:27 +08:00
    @optional 我刚想说有办法,结果发现是我看错 “不存任何东西” 看成了 “不存在任何东西”(尴尬
    janxin
        44
    janxin  
       2019-12-27 14:16:41 +08:00
    好奇你有多少 ip 访问,还能撑爆
    sessionreckon
        45
    sessionreckon  
       2019-12-27 14:18:25 +08:00
    @Sunyanzi +1
    Cookie 里存下 counter + 时间戳 + 校验码就好了,类似 JWT 的验证流程
    Server 校验正确,每次操作增加 counter...
    这种方式不用 server 的缓存支持.减小出错可能性
    binux
        46
    binux  
       2019-12-27 14:23:50 +08:00 via Android
    @Sunyanzi #31 不能挨重放,全靠客户端自律,和裸奔没区别。
    nonce 有不依赖服务器存储的实现方法?
    crab
        47
    crab  
       2019-12-27 14:25:13 +08:00
    把 IP 时间次数记录到 url 请求参数里面,加密签名。
    wangyzj
        48
    wangyzj  
       2019-12-27 14:26:15 +08:00
    Sunyanzi
        49
    Sunyanzi  
       2019-12-27 14:28:51 +08:00
    @binux 「不严谨要求不能挨重放」 ... 双重否定 ... 可能是我措辞的问题比较容易看错 ...

    如果严谨要求不能挨重放的话只能服务端存 nonce ... 然后定期清理 ...
    yuansc
        50
    yuansc  
       2019-12-27 14:32:35 +08:00
    多大数据量呀,,,DB 存不了,LRU Cache + 过期时间呗
    outerws
        51
    outerws  
       2019-12-27 14:33:10 +08:00
    百度之类的防这种也不过是 cookie 带验证并借每几分钟更换一次 cookie 验证码防止跑接口?
    zsdroid
        52
    zsdroid  
       2019-12-27 14:39:23 +08:00
    binux
        53
    binux  
       2019-12-27 14:39:32 +08:00 via Android
    @Sunyanzi #47 「不严谨要求不能挨重放」 我的理解是「不严谨要求」下「不能挨重放」是可选项。
    而且如果存 nonce 我不觉得会比存 IP 少啊。。
    Sunyanzi
        54
    Sunyanzi  
       2019-12-27 14:56:05 +08:00
    @binux 我描述的「不严谨要求不能挨重放」含义全等于「可以在有限范围内挨一些重放」 ...

    在这种情况下 ... nonce 不必需 ... 只要有 timestamp 控制 TTL 就好 ...

    如果要做请求唯一必须有 nonce 这个跑不了 ... 以及存 nonce 和存 IP 最核心的区别是含义不同 ...

    在存储层面 ... IP 是持久化存储 ... 除非有其他规则指定 IP 访问次数的清空规则 ... 否则就是增长慢总量大 ...

    nonce 是瞬时存储 ... 存 nonce 产生的数据会远超存 IP 的量 ... 但超时一般很短 ... 最多一小时就全清空了 ...
    lscho
        55
    lscho  
       2019-12-27 15:00:41 +08:00
    数据库会爆?全中国所有人都来访问你的接口,数据库也爆不了。。。。
    stevenkang
        56
    stevenkang  
       2019-12-27 15:06:16 +08:00
    如果通过服务器端记录客户端对应 ip 的请求次数,数据库会撑爆的
    >>>
    全球所有的 IPv4 加起来 42 亿个,全球总人口 70 多亿。

    到底是 70 多亿用户都来访问导致数据库跟不上呢,还是拥有 70 多亿用户的平台还搭建不出来支持 42 亿条记录的数据库?
    binux
        57
    binux  
       2019-12-27 15:13:19 +08:00 via Android
    @Sunyanzi #52 LZ 问题是,每请求 100 次,弹出一次验证码。并没有时间限制,所以 once 也要一直存着。
    如果有时间限制,那一小时清一次 IP 也没问题啊。
    所以我说存哪个都差不多。
    maichael
        58
    maichael  
       2019-12-27 15:19:40 +08:00
    @zmqking #40 fingerprint 也需要记下来,其实本质上和记 ip 没区别。
    zmqking
        59
    zmqking  
       2019-12-27 15:23:50 +08:00
    @maichael 楼主已经说明是 IP 了,可能是出于安全问题还是怎么的。但这个不记录 IP。只是一个类似 token 的东西!理论上比判断 IP 更加准确,是从多个维度来计算得出的一个值!
    zhttty
        60
    zhttty  
       2019-12-27 15:33:52 +08:00   ❤️ 1
    哪有那么麻烦:
    1、客户端存加密 cookie ;
    2、cookie 包含验证字段、UTC 时间戳、浏览次数、浏览器的一些识别信息、IP 信息(可选)等等;
    3、没有 cookie、cookie 无效、次数超标都弹验证码。
    westoy
        61
    westoy  
       2019-12-27 15:39:08 +08:00
    服务端不做记录没用

    Cookie 计数的前提是客户端会更新 Cookie, 客户端会更新 Cookie 的前提是用会自动托管 Cookie 状态的类库, 问题是...........对方要只是很单纯的把抓到的 Cookie 放 header 里万年不变呢..........
    locoz
        62
    locoz  
       2019-12-27 15:43:09 +08:00 via Android
    「客户端提交的一切信息都不可信」这一点都不知道吗…
    kisshere
        63
    kisshere  
    OP
       2019-12-27 15:46:27 +08:00
    @zhttty 我上面都说了,你这个不可行,我每次都给服务器提供相同的加密 cookie,这个 cookie 是我抓包 chrome 得到的,你服务器每次都只能放行我通过
    ncwtf
        64
    ncwtf  
       2019-12-27 15:50:33 +08:00
    这也不行那也不行?
    ip 放到缓存里加个失效时间有什么不行的。数据库撑爆。。一天访问一次,第一百天访问就要输入验证码?不得加个时间清除么。
    次数+时间+签名 加密放到 cookie 里有什么不行的,就算他伪造 cookie,时间到了不是也失效了?
    用 nginx 脚本应该也能实现需求啊


    小学生都能修改。。有丶牛逼。。
    eason1874
        65
    eason1874  
       2019-12-27 15:52:56 +08:00
    严格限制请求次数就不可能不在服务器记录,无论什么 token 什么 nonce 都一样,纯粹依赖客户端的 nonce 摆脱不了重放。

    记录 100 次就重置了,这能有多少数据量,纯数据来说按 100 万个 token 算才不到 100mb
    markgor
        66
    markgor  
       2019-12-27 15:57:00 +08:00   ❤️ 2
    “最终我还是采用简单粗暴的方法:rand(1,100)>98 && show_captcha();”

    看了下,你好像是想反爬,
    你這個方法我直接棄用這次請求,再發起新的請求,不就繞過去了嗎?
    rbuli
        67
    rbuli  
       2019-12-27 15:57:23 +08:00
    ```
    public boolean flowControl(String ip) {
    String key = UrspReidsPrefixEnum.URSP_FREFIX.getCode() + UrspReidsPrefixEnum.FLOW_CONTROL_FREFIX.getCode() + ip;
    // 限流时间区间
    int seconds = 60;
    // 限流最大允许值
    int max = 100;
    long total = 1L;
    try {
    if (jedisClient.get(key) == null) {
    jedisClient.setex(key, "0", seconds);
    } else {
    total = jedisClient.incr(key).longValue();
    if (jedisClient.ttl(key).longValue() == -1L) {
    jedisClient.expire(key, seconds);
    }
    }
    } catch (Exception e) {
    LOGGER.error("流量控制组件:执行计数操作失败,无法执行计数");
    }
    long keytotaltransations = max;

    // 判断是否已超过最大值,超过则返回 false
    if (total > keytotaltransations) {
    return false;
    }
    return true;
    }
    ```
    xuanbg
        68
    xuanbg  
       2019-12-27 16:48:48 +08:00
    后端完全不存数据,那这个需求臣妾办不到啊!

    但是,访问次数不存数据库可以存 Redis 嘛,key 设置一个合适的过期时间就行了。
    mlboy
        69
    mlboy  
       2019-12-27 17:58:12 +08:00 via iPhone
    计数啊
    mlboy
        70
    mlboy  
       2019-12-27 17:58:59 +08:00 via iPhone
    桶,令牌 了解一下
    jsnjfz
        71
    jsnjfz  
       2019-12-27 17:59:36 +08:00
    nginx 里面写代码或许能搞
    zgq3337
        72
    zgq3337  
       2019-12-27 18:42:39 +08:00 via Android
    为了防重放,再加一个总体 ID 轮链
    pinews
        73
    pinews  
       2019-12-27 18:59:38 +08:00
    cookie 加密
    mreasonyang
        74
    mreasonyang  
       2019-12-27 20:34:40 +08:00 via iPhone
    @wangxiaoaer header 里自定义字段或直接 403 就行了
    yankebupt
        75
    yankebupt  
       2019-12-27 21:55:15 +08:00
    @kisshere
    发 100 个 token,99 层加密,每次请求解密一层返回下一个
    hardcode 验证 token 的逻辑不读库
    api limit rotate 复位的时候直接改下 hardcode
    然后上个防 replay attack 的防火墙(估计比内存数据库还贵,手动狗头)

    /\
    ||
    ||
    ||
    ……
    话说一般外行的话会不会都以为逻辑这样就可以的?
    yankebupt
        76
    yankebupt  
       2019-12-27 22:30:40 +08:00
    如果去 TMD 用户体验的话,好像可以这样

    第一次使用之前,需要调用量申请 api 返回 ip+请求准确时间+定制 salt 静态加密的一个 token
    这个 token 十几秒(时间 1)就会过期,需要立刻使用,把后面请求的申请包在里面,同样返回静态验证过期时间不等(时间 2)的下次使用加密 token

    时间 2 可以宽松一点,一小时 60 次的话可以 2-15 分钟。

    服务器压力变大的时候缩短时间 2,然后把 spam 申请 api 的 ip 加入黑名单直接 ban 掉就是了。
    这样防重放防火墙逻辑可以把窗口只保留 2-15 分钟……带宽不大的话两分钟 D 不满数据库……

    记得之前一个外行还是不外行的站就是这么搞的,年代久远,想不起来是哪个了。
    yankebupt
        77
    yankebupt  
       2019-12-28 01:37:00 +08:00
    @kisshere 当然如果和压力完全无关单纯只是想恶心人,可能你想要的是
    if (([minute of day] / [[typical interval of your api]) +- rand(md5(src-ip))*[random size] ) mod 100 >=98
    captcha()
    if fail
    add-ip-to-must-captcha-list-for-24h-until-success()
    fi
    fi
    happyz90
        78
    happyz90  
       2019-12-28 07:11:34 +08:00 via Android
    不是精确的 100 次可以接受不?
    MoccaCafe
        79
    MoccaCafe  
       2019-12-28 07:31:52 +08:00 via iPhone
    前端传来的数据是不可信任的,尤其是这种不带凭证又不带 ip,除非你对所有用户都做一样的限制
    hulonghe
        80
    hulonghe  
       2019-12-28 07:53:58 +08:00 via Android
    开放授权码(后端限制授权码使用次数,合理控制分发),前后端都记录授权次数,校验对比。授权码生成得有规律,但又不可解,就像是 uuid。
    后端增加一个授权分发机制,如果达到异常点,控流,查来源,封访问权限(或者限制下次可使用时间)
    KuroNekoFan
        81
    KuroNekoFan  
       2019-12-28 07:54:02 +08:00 via iPhone
    cookie 有个 http only 的属性
    KuroNekoFan
        82
    KuroNekoFan  
       2019-12-28 07:57:10 +08:00 via iPhone
    不过也能从 dev panel 编辑,感觉可以从非对称加密的角度思考一下
    foamvalue
        83
    foamvalue  
       2019-12-28 08:36:15 +08:00
    服务器缓存校验一下,redis 之类的。
    markgor
        84
    markgor  
       2019-12-28 13:00:32 +08:00
    如果按標題來說,可否走 ws 協議?


    進入頁面->輸入驗證碼->建立 ws 通道->ws 判斷驗證碼-->正確執行返回並計次->達到 100 次重走輸入驗證碼流程。
    錯誤重來<-|
    zgq3337
        85
    zgq3337  
       2019-12-28 21:50:43 +08:00 via Android
    以 URL 为数据库,服务器做加解密,为防无影,首次可能需要验证码
    encro
        86
    encro  
       2019-12-30 09:32:18 +08:00
    redis hyperloglog 就是干这事的
    encro
        87
    encro  
       2019-12-30 09:35:26 +08:00
    我这一个回答,至少值 1000RMB 吧
    encro
        88
    encro  
       2019-12-30 09:37:37 +08:00
    只是不明白,
    一台普通 32G 服务器,
    将中国所有 IPV4 都存下来,
    也不会爆吧。

    谁来算以下?
    webcoder
        89
    webcoder  
       2019-12-30 14:43:50 +08:00   ❤️ 1
    借用三楼的方案,第一次请求输入验证码,然后生成一个带专有及唯一属性(GUID+验证码+时间后 md5 之类的)的令牌(token),每次请求必须带上该令牌。令牌丢失就弹验证码。这就解决了身份验证问题。
    把令牌放到 redis 里记录请求次数,请求超限,令牌失效,重新输入验证码来生成新的令牌。
    不要把令牌放 session 里,因为如果你的请求量太大的话,令牌数估计也不少。所以尽量使用 redis 这种更专业一点的东西来处理。

    这个方案比你用 ip 记录更好,可以避免用代理伪造 ip 来刷接口。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2887 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 13:40 · PVG 21:40 · LAX 05:40 · JFK 08:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.