1

我一直在研究在我的网站上实现持久登录的最佳(和最安全)方法,我提出了以下建议:

当用户登录时,会创建一个包含用户 ID/用户名和随机生成的数字(令牌)的 cookie。令牌与用户 ID/用户名一起存储在关系表中。每次加载仅限成员的页面时,都会根据关系表检查此 cookie,如果它存在与令牌匹配,则登录有效并且可以加载页面。但是,如果不是,则登录无效,cookie 被销毁,并提示用户登录。

我在想...为了在每次加载页面时节省数据库访问,我还可以有一个会话变量,例如持续 10 分钟,并在浏览器关闭时自动销毁。如果会话是活动的,那么它会被刷新并且用户可以继续。如果会话过期,但 cookie 仍然有效,请检查 cookie,重置令牌,将新令牌存储在数据库中(同时消除旧令牌,或将其存储在存档表中以供将来参考),然后重置 cookie使用新的令牌值。

但是,会话将包含什么内容?怎么能不简单地用一些 JavaScript 伪造会话呢?也许会话包含单向加密哈希?将使用什么来生成该哈希(用户 ID 等)?

我有点想从这里去哪里。我得到了 cookie 的东西,但是使用临时会话(以避免每次加载页面时重复调用数据库)让我望而却步。有什么帮助吗?谢谢。

4

2 回答 2

2

根据RFC 4122 ,不建议使用 UUID ,它指出

不要假设 UUID 很难猜;它们不应用作安全功能。

我建议将以下所有信息组合并乘以散列,同时使用存储在服务器中的公钥对其进行加密。

  • UserId(或注册时为每个用户生成的用户 UUID)
  • 加密他/她的密码(被认为是每个用户加密的私钥)
  • 时间戳
  • 客户端操作系统
  • 客户端用户代理(浏览器名称)

对于存储令牌,您可以使用在大公司中大量使用的memcache ,如果您专注于持久性,则可以使用redis 。

确保您的 cookie 具有以下属性,以获取有关cookie的更多信息

  • 仅 HTTP cookie
  • 安全 Cookie
于 2014-02-08T09:10:50.250 回答
1

Cookie 应该没问题(另一种方法是将其存储在 HTTP 标头中),但是我认为不需要将用户名/ID 存储在 cookie 中。令牌本身就足够了。您可以使用UUID作为令牌。将其与用户名和 last_access_timestamp 一起存储在数据库表中。并且只在每个请求上发送令牌(在 cookie 或 HTTP 请求标头中)。在我看来,这足以实现会话。

用户成功登录时会生成一个令牌,存储在数据库中并传递给用户。每当用户访问网页时,都会在请求中传递令牌并进行验证。如果有效,则刷新 last_acces_timestamp 并且用户可以继续。验证中的查找将通过令牌完成,您可以使用用户名进行身份验证和授权。如果令牌无效或过期,则将用户转发到登录页面。

可以使用 cron 作业或在创建新会话时定期从数据库中删除过期会话。

出于性能原因,您可能会考虑将会话存储在内存中的 hashmap 中。因为总是更新数据库可能会很昂贵。

还要考虑使用 HTTPS,以防止人们嗅探令牌。

几个月前,我通过以下方式解决了这个问题: https ://stackoverflow.com/questions/12829994/java-custom-session-implementation-expired-sessions

于 2012-12-19T20:10:30.230 回答