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

验证回答是否正确展示内容,如何做比较安全?

  •  
  •   tanteng · 2015-11-13 09:41:11 +08:00 · 3032 次点击
    这是一个创建于 3327 天前的主题,其中的信息可能已经有所发展或是发生改变。

    效果如图

    验证回答是否正确展示内容,如何做比较安全

    有这样一个表单,需求就是回答问题正确才能查看内容,在一定时间如 1 天内再次访问不用回答问题,不用登录会员系统。请教各位一般通常可行的办法是什么?

    目前的做法是:回答正确了,写一个 cookie 值为 1 ,下次来判断这个 cookie 值是否为 1 ,否则需要重新回答问题,这样做明显不安全,伪造一个 cookie 访问不就可以查看到受保护的内容了。

    想过生成一个 token ,存到 cookie ,比如 md5(一个值+salt),但是存什么呢,要下次回答问题正确的用户来了可以校验不用再回答问题,根据什么规则存呢?

    小站,没有 redis ,不考虑 redis 方案。

    第 1 条附言  ·  2015-11-16 15:27:00 +08:00
    页面每次刷新问题会随机抽取
    30 条回复    2015-11-27 01:24:34 +08:00
    tanteng
        1
    tanteng  
    OP
       2015-11-13 09:55:19 +08:00
    这样是否可行?
    回答问题正确,存一个 cookie ,值是 md5(今天日期+salt),下次访问校验的时候,计算 md5(今天日期+salt)是否和存的 cookie 相同,就可以了。但是这样做,只能不用再次回答问题的有效时间是隔天就失效。

    大家有更好的办法吗?
    emric
        2
    emric  
       2015-11-13 10:06:46 +08:00
    Cookie 不安全, 用 Session 不就好了.
    yeyeye
        3
    yeyeye  
       2015-11-13 10:07:59 +08:00
    这类用 Cookie 和 Session 都不合适。直接按 IP 来存数据库
    tanteng
        4
    tanteng  
    OP
       2015-11-13 10:12:17 +08:00
    @yeyeye ip 不可靠,同一个局域网这么多人,其中一个人回答问题正确,其他人都可以访问了
    tanteng
        5
    tanteng  
    OP
       2015-11-13 10:14:27 +08:00
    @emric 需求是回答问题正确,下次再次访问不需要再验证,通过 session 怎么判断,肯定要存 cookie
    adorazhang
        6
    adorazhang  
       2015-11-13 10:17:12 +08:00
    同意一楼的做法
    hvsy
        7
    hvsy  
       2015-11-13 10:17:15 +08:00
    随机生成一个值写入 cookie 里面,然后存放到数据库里面.如果没有数据库.就生成一个临时的文件.文件名就是这个值,通过文件的创建时间进行判断.
    mcfog
        8
    mcfog  
       2015-11-13 10:17:30 +08:00
    adorazhang
        9
    adorazhang  
       2015-11-13 10:18:17 +08:00
    setcookie 时可以设置时长的
    PublicID
        10
    PublicID  
       2015-11-13 10:22:21 +08:00 via Android
    不怕被爆破吗?
    oott123
        11
    oott123  
       2015-11-13 10:23:26 +08:00 via Android
    一楼可行
    另外不存 1 ,存一个固定值也不是不可以,比如说答案
    vitovan
        12
    vitovan  
       2015-11-13 12:48:30 +08:00 via Android
    11 楼+1 ,
    存用户输入的答案,每次请求进行答案校验,正确则跳。
    skydiver
        13
    skydiver  
       2015-11-13 12:51:09 +08:00
    不就是 Session 么……这个和登录状态不是类似的一回事么
    realpg
        14
    realpg  
       2015-11-13 12:53:37 +08:00
    1 高安全性版本, cookies 存储一个 key 服务器存储一个对应的 key 两者独一无二的匹配对应允许

    2 你这个需求的精简版,直接把用户回答的历史答案放到 cookies 载入页面取 cookies ,如果不对就继续显示认证
    ck65
        15
    ck65  
       2015-11-13 13:06:13 +08:00
    jwt +1
    可通过参数设置一天过期
    gamexg
        16
    gamexg  
       2015-11-13 13:22:53 +08:00
    服务器通过 salt 生成一个密钥,然后密钥加密过期时间保存到客户 cookies 。
    每次读客户端提交的 cookies 解密得到过期时间。
    gamexg
        17
    gamexg  
       2015-11-13 13:23:46 +08:00
    如果有服务端 Session ,直接在 Session 保存过期时间。
    tanteng
        18
    tanteng  
    OP
       2015-11-13 13:57:31 +08:00
    @vitovan
    @realpg
    问题是随机的,每次刷新页面问题不一样
    domty
        19
    domty  
       2015-11-13 14:16:57 +08:00
    这不就是一种另类的登录方案吗?
    用 session 啊 或者类似 session 的有超时时间的服务器端缓存啊。
    cookie 存 sessionid , session 就是个以 sessionid 为 key 的键值对啊,值对象里存是否通过验证字段。
    超时清楚该 session
    tanteng
        20
    tanteng  
    OP
       2015-11-13 14:32:49 +08:00
    其实用 cookie ,安全性没办法控制吧,就算存的加密的 cookie ,我把 cookie 给别人,别人不可以模拟请求了
    tanteng
        21
    tanteng  
    OP
       2015-11-13 14:35:47 +08:00
    如果要保证安全,那每次进页面都要输入问题答案
    domty
        22
    domty  
       2015-11-13 14:36:43 +08:00
    @tanteng
    别想太多了, cookie 在谁手里谁就是主人,最多超时时间设短点让人家答题频繁点。
    再想做下去,感觉你要付出的成本会高很多,而提升的效果未必理想。
    dant
        23
    dant  
       2015-11-13 14:39:24 +08:00 via Android   ❤️ 1
    答题正确就把数据放 local storage 里(逃
    littlehz
        24
    littlehz  
       2015-11-13 19:23:58 +08:00
    这个需求和用于判断登录的 session 有何区别?
    Slienc7
        25
    Slienc7  
       2015-11-13 20:37:38 +08:00
    setcookie(xxxhash(用户答案+"日期 20150101"));

    if(xxxCookie === xxxhash(用户答案+"日期 20150101")){
    balabalabala}
    yixiang
        26
    yixiang  
       2015-11-14 11:14:07 +08:00
    数据库里一个表,两个字段:随机字符串,对应班级。生成时间。回答正确一次生成一行,并将随机字符串存到本地。每次访问时重新生成字符串。可以保证就算 cookie 被分享也立刻失效。比 cookie 值等于 1 好的地方在于不能直接被伪造。
    当然用户怎么都可以分享 cookie ,但在那之前,他可以分享问题的答案啊。
    是我的话直接用 session ,在有用户抱怨麻烦的时候再改吧。
    tanteng
        27
    tanteng  
    OP
       2015-11-16 14:31:44 +08:00
    @dant 这个确实是一个新的思路啊
    tanteng
        28
    tanteng  
    OP
       2015-11-16 14:37:14 +08:00
    @dant 可是我看到这么一句话:浏览器使用 Cookie 进行身份验证已经好多年,既然现在 localStorage 存储空间那么大,是否可以把身份验证的数据直接移植过来呢?目前来看,把身份验证数据使用 localStorage 进行存储还不太成熟。

    安全性是个问题。
    dant
        29
    dant  
       2015-11-18 08:15:43 +08:00 via Android
    @tanteng 把验证之后能看到的内容放进去
    mrliusg
        30
    mrliusg  
       2015-11-27 01:24:34 +08:00
    生成一个 token ,存到 cookie 。
    再次访问的时候根据 cookie 的 token 查询是否过期,过期取消 cookie 。
    成功访问后重新生成新 token 并替换原 token 。

    最大的安全漏洞在人,所以强制过期是要有的。存答案的就算了吧……
    我现在使用的是 session ,验证通过即存当前时间到 session ,服务端判断是否过期, PHP+redis 管理 session
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   973 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 22:57 · PVG 06:57 · LAX 14:57 · JFK 17:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.