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

怎么实现每天每个 ip 有且只能投一票的功能

  •  
  •   caserest · 2015-05-09 17:29:33 +08:00 · 9789 次点击
    这是一个创建于 3496 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我一朋友这么想 就是把每个投票的ip放到数据库中然后每天清理一下数据库实现每天只能投一票的功能。但是如何每天清理数据库呢?我觉得不靠谱,但是又想不到有什么其他好办法。

    75 条回复    2016-06-30 17:15:15 +08:00
    hjc4869
        1
    hjc4869  
       2015-05-09 17:35:37 +08:00
    将投票IP 投票时间存入数据库,投票的时候检查在投票当天是否有该IP的投票记录。
    imlonghao
        2
    imlonghao  
       2015-05-09 17:40:36 +08:00 via Android
    您就不能存多一个时间的column么?
    liboyue
        3
    liboyue  
       2015-05-09 17:52:02 +08:00 via Android
    不靠谱,用路由器的不得跪了
    shiny
        4
    shiny  
       2015-05-09 17:52:25 +08:00
    redis 设置过期时间
    giuem
        5
    giuem  
       2015-05-09 17:52:56 +08:00 via Android
    移动宽带全省就几个ip。。
    ssacpklnm
        6
    ssacpklnm  
       2015-05-09 17:55:21 +08:00 via Android
    @giuem 这个2333
    ob
        7
    ob  
       2015-05-09 17:58:49 +08:00 via Android
    加验证码妥妥的
    zeyexe
        8
    zeyexe  
       2015-05-09 18:04:25 +08:00
    设置cookies可能好一点,大部分人应该不知道cookies是什么
    hjc4869
        9
    hjc4869  
       2015-05-09 18:04:46 +08:00
    @ob 验证码可以找几个大妈帮忙刷票,一个小时刷几千票没啥问题。。
    iyaozhen
        10
    iyaozhen  
       2015-05-09 18:22:13 +08:00 via Android
    配个定时任务清呗
    cvmax
        11
    cvmax  
       2015-05-09 18:57:09 +08:00
    @zeyexe 非得补一刀。挺好。
    billlee
        12
    billlee  
       2015-05-09 18:58:27 +08:00
    配个 cron 任务就可以实现每天清理数据库
    leofml
        13
    leofml  
       2015-05-09 19:51:45 +08:00
    redis ttl
    rtyurtyu
        14
    rtyurtyu  
       2015-05-09 19:58:20 +08:00
    开一个4G的数组i,i[ip]==1;
    到点了就delete []i再开好了
    wolong
        15
    wolong  
       2015-05-09 20:01:49 +08:00
    @zeyexe 碰到懂的人,写个程序挂机投,网速好不限制访问的话5秒一个应该不成问题。然后把程序多分给几个人挂。
    gdtv
        16
    gdtv  
       2015-05-09 20:04:46 +08:00
    最靠谱的还是绑定微信,在微信里投票,一个微信号只能投一票
    shootsoft
        17
    shootsoft  
       2015-05-09 20:18:17 +08:00
    强烈建议这种业务用redis处理。

    redis的key设置直接用 ip 就行,如果ip存在,就表示存在了。

    如果要限制每个IP/每天只能投一次,就每天凌晨用crontab的job清理一次redis。如果要限制每个IP,没24小时只能投放一次,就给redis的key设置一个过期时间为24小时。
    loveyu
        18
    loveyu  
       2015-05-09 21:37:03 +08:00
    有个问题就是部分地区IP很少,类似移动之类的,很多人直接投不了
    em70
        19
    em70  
       2015-05-09 21:39:43 +08:00 via Android
    首先不能纯IP限制,还要加上cookie,然后cookie值和IP,时间一起存到数据库。每次投票,在数据库查找12小时内的cookie值和IP记录是否与提交的信息有重复的,任一个重复都返回错误。

    如果非要在24点限制,就每次投票查找今天0点到现在时间内的IP或者cookie是否重复即可。

    不用考虑清空数据库,留下原始数据,还能人工K掉恶意投票。
    jarlyyn
        20
    jarlyyn  
       2015-05-09 21:40:36 +08:00
    记录一下每个人最后一次投票时间。
    xiaozhizhu1997
        21
    xiaozhizhu1997  
       2015-05-09 21:42:01 +08:00
    现在NAT盛行...采用cookies似乎更合适。
    ys0290
        22
    ys0290  
       2015-05-09 21:50:56 +08:00 via iPhone
    cookie过滤一遍,剩下的放服务器过滤
    xjdrew
        23
    xjdrew  
       2015-05-09 22:18:06 +08:00 via Android
    @shootsoft 思路正确。不过不需要crontab清理。redis自带expire,用来做这种定期cookie的
    laoyuan
        24
    laoyuan  
       2015-05-09 22:21:21 +08:00
    md5(ip.date(Ymd, time())
    kslr
        25
    kslr  
       2015-05-09 22:56:57 +08:00 via Android
    话说那些自动失效的,加个投票时间戳不就行了
    reeco
        26
    reeco  
       2015-05-09 22:57:31 +08:00 via iPhone
    大多数数据库支持事件的,不需要cron
    issues
        27
    issues  
       2015-05-09 23:01:21 +08:00   ❤️ 1
    ip 不行 拨号用户可以重新拨号获取新ip, 当然cookie也不行,本地cookie可以删除。mac地址,当然要想真想搞刷票, mac也貌似也可以伪造。
    issues
        28
    issues  
       2015-05-09 23:03:42 +08:00
    想要真正实现这样的不能刷票是很难的, 只有提升这种刷票的难度。难度大了,自然会放弃。
    luw2007
        29
    luw2007  
       2015-05-09 23:06:51 +08:00
    每个登录用户只能投一票。
    可以使用openauth接入qq,weibo的账户
    wusuopuBUPT
        30
    wusuopuBUPT  
       2015-05-09 23:08:46 +08:00
    zyue
        31
    zyue  
       2015-05-09 23:10:29 +08:00
    redis 妥妥的
    gladuo
        32
    gladuo  
       2015-05-09 23:18:14 +08:00
    面向普通人就cookies~

    程序员投票还是微信吧~
    xiaowangge
        33
    xiaowangge  
       2015-05-09 23:43:07 +08:00 via Android
    腾讯CMem 设置过期时间。
    lwch
        34
    lwch  
       2015-05-09 23:48:43 +08:00
    redis有条命令叫setex

    http://cxx.party就是这么实现的。。
    hello2t
        35
    hello2t  
       2015-05-10 00:04:25 +08:00
    redis存,key value 就好了,定时清理
    zonghua
        36
    zonghua  
       2015-05-10 00:11:36 +08:00 via iPhone
    实名认证的登录
    flowerwrong
        37
    flowerwrong  
       2015-05-10 00:51:40 +08:00 via Android
    @gdtv 淘宝分分钟刷哭你。
    flowerwrong
        38
    flowerwrong  
       2015-05-10 00:52:53 +08:00 via Android
    TTL靠谱,最好配合cookie
    Septembers
        39
    Septembers  
       2015-05-10 01:00:58 +08:00 via Android
    @em70
    跟QQ OAuth绑到一起会更靠谱一些
    一个QQ有效票数只能一次之类的
    毕竟大规模注册QQ刷票是比较不现实的
    如果基于IP的话去阿里云开1000个最低配的VPS一小时加高匿代理 不就一下刷起来了
    crab
        40
    crab  
       2015-05-10 01:13:46 +08:00   ❤️ 1
    还是得靠验证码。
    另外票数可以不公开,结束后才公开。想刷票的也没调试环境。
    mornlight
        41
    mornlight  
       2015-05-10 01:21:27 +08:00
    @issues MAC地址不行,服务器拿不到的。
    sing1ee
        42
    sing1ee  
       2015-05-10 01:28:13 +08:00
    只考虑问题本身,一圈儿看下来,redis的方案最靠谱儿。
    issues
        43
    issues  
       2015-05-10 01:30:13 +08:00
    @mornlight 这个是通过js获取,作为参数传入是可以的
    yaoyuan1072
        44
    yaoyuan1072  
       2015-05-10 06:54:47 +08:00 via Android
    前几天正在研究这个问题,如何获得内网的IP呢?因为有时候一个公司几百号人就一个IP。。。
    gamexg
        45
    gamexg  
       2015-05-10 09:37:46 +08:00
    @yaoyuan1072 获得内网IP
    /t/167354
    zhicheng
        46
    zhicheng  
       2015-05-10 10:12:57 +08:00 via Android
    @issues 我真的特别有兴趣知道,你是如何用 JS 获取 Mac 地址的。还是你只是瞎说的。
    can
        47
    can  
       2015-05-10 10:30:39 +08:00
    基本就是楼上回复的这些了,微信绑定,IP,cookie,验证码。想防刷票的关键是看你代码怎么写了,写的好的话就能挡得住。建议楼主乌云搜索刷票,我还是想说句来回这点事,关键看你代码怎么写了。
    issues
        48
    issues  
       2015-05-10 11:22:23 +08:00
    @zhicheng
    ActivieX实现的。
    当然这个肯定有局限性的,只对windows系统ie浏览器。
    要想跨平台,就用Applet。
    solupro
        49
    solupro  
       2015-05-10 12:39:07 +08:00
    @issues 同楼上,对JS获取MAC地址很感兴趣,求教!
    solupro
        50
    solupro  
       2015-05-10 12:40:29 +08:00
    @issues 囧,没刷新,现在才看到你的方法。ActiveX局限性太大了。
    flynaj
        51
    flynaj  
       2015-05-10 13:16:28 +08:00
    这样都没用.要防止作弊就是一个用户只能投一次!
    flowerwrong
        52
    flowerwrong  
       2015-05-10 13:24:12 +08:00 via Android
    @flynaj 这样也没用,可以刷单。
    s51431980
        53
    s51431980  
       2015-05-10 17:14:37 +08:00
    只要在客户端,就有作弊的可能,cookie、验证码最终都敌不过廉价的人力成本
    caserest
        54
    caserest  
    OP
       2015-05-10 18:37:53 +08:00 via Android
    谢谢各位大神
    handleyan
        55
    handleyan  
       2015-05-10 19:43:06 +08:00
    1、要想识别一台机器的话,可以尝试使用一下cavas,即通过画cavas然后md5来唯一标识一台机器,据说能保证唯一性,我没试过,楼主试过如果有效了可以分享一下
    2、在有了唯一标识之后,要想限制一天一次,如果非要用数据库,可以用乐观锁,一条update语句就行了,不过如何暴露地使用数据库在并发比较大情况下是不建议的,除非你准备搞个分布式数据库,这样成功也大了。最好是使用上面很多人提到memcached、reids等分布式内存式的存储工具,这些工具一般也都有乐观锁的实现。
    quix
        56
    quix  
       2015-05-10 20:58:43 +08:00   ❤️ 1
    @handleyan 主意拼写哈。。一段里错了好多个。。 有拼写强迫症的看不下去了
    handleyan
        57
    handleyan  
       2015-05-10 21:05:56 +08:00 via iPhone
    @quix 现在的英文听说读写只剩读还行了…以后发帖前一定用拼写软件看看,丢不起这人呐…
    powergx
        58
    powergx  
       2015-05-10 21:14:10 +08:00
    加验证码,要么用第三方账号
    世界上有代理服务器,还有肉鸡,刷票是挡不住的
    frankzeng
        59
    frankzeng  
       2015-05-10 21:39:50 +08:00
    用微信关注吧,关注了拿openid去查一下,应该能确保真实
    flowerwrong
        60
    flowerwrong  
       2015-05-11 00:50:58 +08:00 via Android
    @powergx 我也觉得挡不住,正为微信刷票而烦恼。
    flowerwrong
        61
    flowerwrong  
       2015-05-11 00:51:44 +08:00 via Android
    @frankzeng nonono,淘宝一下,一堆商家
    ryd994
        62
    ryd994  
       2015-05-11 03:10:08 +08:00 via Android
    @handleyan 不需要上锁,多一票少一票不怕的
    jakehu
        63
    jakehu  
       2015-05-11 07:11:16 +08:00
    我以前做的是写入数据库,每次写入前都清楚一个小时之前的
    FastMem
        64
    FastMem  
       2015-05-11 09:25:20 +08:00
    数据表
    id,ip_address,date
    1,123,123,123,123,time
    然后每次投票检查日期呗。。
    ryd994
        65
    ryd994  
       2015-05-11 09:30:54 +08:00 via Android
    @FastMem IP直接转换成32位整数,性能还更好
    FastMem
        66
    FastMem  
       2015-05-11 09:33:32 +08:00
    @ryd994 soga。受教
    donghouhe
        67
    donghouhe  
       2015-05-11 10:55:49 +08:00
    看到说用cookie区分的,哎呀,太贴心了,代理都不用挂了!刷票代码写起来太方便了!
    millken
        68
    millken  
       2015-05-11 11:43:16 +08:00
    sun019
        69
    sun019  
       2015-05-11 11:44:50 +08:00 via Android
    只有注册用户才能投!!!其他的都是浮云,被投票搞翻过几次服务器的路过!
    shepherd
        70
    shepherd  
       2015-05-11 12:01:56 +08:00
    搞个手机验证码?或者直接用手机投票
    miao1007
        71
    miao1007  
       2015-05-11 13:07:06 +08:00
    用微信,妥妥的。
    yanze0613
        72
    yanze0613  
       2015-05-11 13:13:40 +08:00
    每天重建一张表,投票的时候记录ip丢进去,第二天换个表
    数据库自动方便可以用作业或者shell
    66beta
        73
    66beta  
       2015-05-11 13:23:52 +08:00
    注册登录吧,不管是自己做,还是接入第三方
    roychan
        74
    roychan  
       2015-05-22 21:11:45 +08:00
    如果面对的客户大部分是小白的话,完全可以在 Session 里加一个 waterproof 给个值为1,每次收到请求判断 session 里有没有这个 key。然后 24 小时过期就行了,很节省资源。
    Wichna
        75
    Wichna  
       2016-06-30 17:15:15 +08:00
    @millken 这个换一个浏览器就不一样了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1314 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 23:38 · PVG 07:38 · LAX 15:38 · JFK 18:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.