我希望我的网站有一个用户可以点击的复选框,这样他们每次访问我的网站时都不必登录.我知道我需要在他们的计算机上存储一个cookie来实现它,但该cookie中应包含哪些内容?
此外,是否存在常见错误,需要注意保持此cookie不会出现安全漏洞,这可以避免,同时仍然提供"记住我"功能?
1> splattne..:
改进的持久登录Cookie最佳实践
您可以使用此处描述的此策略作为最佳实践(2006)或此处描述的更新策略(2015):
当用户使用"记住我"选中成功登录时,除了标准会话管理cookie之外,还会发出登录 cookie.
登录cookie包含系列标识符和令牌.系列和令牌是来自适当大空间的不可取的随机数.两者都存储在数据库表中,令牌被哈希(sha256很好).
当未登录的用户访问该站点并显示登录cookie时,将在数据库中查找该系列标识符.
如果存在系列标识符并且令牌的散列与该系列标识符的散列匹配,则认为用户已经过身份验证.一个新的令牌生成,该令牌一个新的哈希值存储在旧记录,一个新的登录cookie被发送到用户(也没关系,重新使用系列标识).
如果系列存在但令牌不匹配,则假定盗窃.用户收到强烈警告的警告,并删除所有用户记住的会话.
如果用户名和系列不存在,则忽略登录cookie .
这种方法提供了纵深防御.如果有人设法泄漏数据库表,则不会让攻击者为冒充用户打开大门.
@HiroProtagonist系列标识符用于防止DoS攻击.没有它,我可以快速编写一个脚本,用每个用户名和一个无效令牌命中你的网站,记录你网站上的每个人.
另见:http://stackoverflow.com/questions/549/the-definitive-guide-to-website-authentication-beta#477579你不应该阅读'改进'版本
此外,关于这个模型,它是什么阻止攻击者窃取,而不是将cookie放在他的计算机上并从被黑客入侵的计算机中删除cookie.他的计算机将根据需要进行身份验证和更新,而不会被黑客攻击的计算机知道吗?唯一的变化是黑客计算机用户必须再次登录并设置记住我.被黑客用户是否认识到这一点是不确定的.
这样做的问题是你在cookie中公开了用户名,尽管这就是Gmail的用途.为什么需要系列ID和令牌?难道没有更大的标记可以吗?
@roverred如果您只使用一个长令牌,并在任何无效令牌到达时销毁用户的所有会话,我可以编写一个脚本,使用每个用户名点击您的站点,并使用令牌的所有0来记录所有用户.在循环中运行它,没有人可以有意义地登录.如果在服务器对抗会话之前需要有效的系列令牌,则会阻止DoS攻击.
如果用户的互联网连接不良,这可能是收到新令牌时的问题?例如,用户请求使用令牌登录,互联网连接断开,服务器生成新令牌,用户未收到新令牌,用户再次使用旧令牌尝试,这被视为黑客攻击并且所有令牌都从数据库中删除,用户现在必须再次登录
这个解决方案是WRONG,它不处理cuncurrency:如果两个remember-me身份验证请求同时到达,使用相同的remember-me cookie,第一个成功并更改令牌,第二个导致unsucceesfull身份验证,并且误报(因为第一次请求已经更改了令牌).(当浏览器启动时会出现这种情况,并且会在两个浏览器选项卡中恢复该站点.)
@altvali当提供有效的用户名/密码组合以验证用户(而不是令牌)时,将发出新的系列标识符.这将启动一系列新的随机令牌,用于识别此特定(长)登录会话.
还要确保更改用户的密码或密码恢复信息需要原始密码.如果cookie被泄露,攻击者无法阻止原始所有者访问该帐户.
我昨天实现了这个解决方案,我认为它运行良好,未提及的是如何处理数据库中的"孤立"身份验证信息.当用户手动清除其cookie缓存时,数据库中的身份验证信息将被孤立.也许在表中实现自动更新时间戳并在一定年龄内手动删除所有身份验证数据将是一个好主意.
当您在地址栏中输入网址时,Chrome会发送加载请求.这可能导致记住我的代码过早地执行,这将在用户按下地址栏中的enter时执行实际请求时使令牌无效.除了使用在后续登录期间不会更改的静态cookie之外,我没有看到解决此问题的简单方法.其他人遇到这个问题?
谁能解释系列标识符什么时候会改变?如果从来没有,那么存储加密的用户名和令牌就足够了?
序列标识符的整个概念没有意义,因为它在这里描述。
@tvanfosson ......你为什么需要这个?只需生成一个新的UNIQUE令牌......没有理由让一个用户不能拥有多个令牌...每个登录一个....令牌A,令牌B,令牌C ......不需要一个系列标识符.
我发布了一个关于这个答案的问题:http://stackoverflow.com/questions/10957584/stay-logged-in-best-practices-how-does-a-username-in-the-cookie-make-it-更-SE
为什么不添加用户名的哈希呢?
@Yar包含电子邮件ID以保持唯一性,因为可能会发生为两个不同帐户生成相同的令牌
这个问题和答案非常奇怪.如果用户ID应存储在客户端上并与系列和令牌一起发送以进行验证,则不会提及.所以读者必须猜测该系列可能是用户的替代品.第二个问题,问题是关闭的,所以只有信息来源是评论.第三个问题:并发.它并不小,因为一次打开2个标签中的同一个网站非常频繁.并且你不希望它在1%的时间内失败.
@ChrisMoschini该系列如何防止DOS攻击?是什么让我无法编写脚本来尝试将令牌设置为“ 1”的系列Cookie的所有变体,所以脚本将遍历并注销所有人
2> dragonmantan..:
我会存储用户ID和令牌.当用户回到站点时,将这两个信息与数据库条目之类的持久性进行比较.
至于安全性,只是不要在其中放置任何允许某人修改cookie以获得额外好处的东西.例如,不要存储其用户组或密码.任何可以修改以避免安全的内容都不应存储在cookie中.
3> jonnii..:
存储他们的UserId和RememberMeToken.当他们登录时记住我检查生成一个新的RememberMeToken(使任何其他标记的机器无效,记住我).
当他们返回时通过记住我的令牌查找它们并确保UserId匹配.