Rails 诸位看看我这样理解 rails 的用户登陆过程是不是正确的

so_zengtao · 发布于 2014年05月27日 · 最后由 yiming 回复于 2014年05月28日 · 2036 次阅读
Abca79

所谓的用户登陆

其实就是在网站的每个页面(也就是 每个控制器 的 每个动作 都能取到 current_user )

然后在浏览器里的cookies里面存储的是一个没有加密的 hash_string1

然后在数据库里面存储一个加密的hash_string2 (加密hash_string1)

然后每个页面通过cookies拿到 hash_string1 然后加密之后找到 user 这个找到的 user就是current_user

然后就可以对这个current_user进行各种蹂躏了对么 亲们?

共收到 21 条回复
4375

不是. rails 常用的 devise 没看过源码不清楚。sorcery 和 @rei 在campo里自己写的登录逻辑都是记录user_id。每次请求会自动用 user_id 查询user表。

1

#1楼 @saiga devise 应该是存了 user_id 和 token,我也打算改成这样,避免 cookie 泄露之后无法让它失效。

Abca79

#2楼 @Rei - - 你的意思是改成我这个样子么 卧槽 你怎么是第一个会员

4933

#3楼 @so_zengtao 因为你遇到好心的大神了。

1

#3楼 @so_zengtao 我打算改成 session 存 user_id 和 token,根据两个值来判断登录用户。

Abca79

#5楼 @Rei 我明白你说的是什么 貌似通过token可以取到user对象的 在users表格存一个字段 (新手说的不对请指正)

1

#6楼 @so_zengtao 用 id 查可以少加一个索引。并且我在 campo 的实现里面没有设 token 字段,而是把 password_digest 再 SHA512 hash 一遍得到一个 token。

4375

#6楼 @so_zengtao token 只是拿来校验是否过期,当 token + id 给了服务器,服务器会到一张专门记token的表查询是否存在,不存在则忽略id直接清空session,反之根据id拿到user对象

Abca79

#8楼 @saiga 我的意思是利用session登陆。你的token应该指的是移动端没有session的token把

Abca79

#7楼 @Rei 你说的是ruby-china么 我去git看看

Abca79

#7楼 @Rei 原来是rails的论坛框架。好人一生平安

96

#11楼 @so_zengtao @Reicampo

刚刚接触Rails,我也不知道比较安全,高效的做法。

Rails Tutorial里是每次登录后用 url_base64 生成一段16位的字符串(两段字符串碰巧相同的几率非常非常小)姑且叫 remember_token。然后对这个16位字符串做hash存到数据库users表的一个字段下(为了查询效率这个字段是做index的)。你的app把 remember_token 存到用户浏览器的cookie里。已经登录的用户每次访问页面时,会尝试拿 remember_token 做hash去数据库查询用户。当然,为了避免每次都查浪费效率,做了 ||= 处理

self.current_user ||= User.find_by(remember_token_digest: hashed_remember_token)
  1. 如果cookie泄露,攻击者可以自动登录你的账号;
  2. 如果你显式地登出,那么remember_token会清除,之前泄露的remember_token就失效了;
  3. 一旦服务器数据库泄露,由于remember_token是hash后存的,那么攻击者是很难逆向出原始remember_token的。
Abca79

#13楼 @yiming 这个和我的做法差不多

96

#14楼 @so_zengtao @Rei 目前在Campo的做法,倘若用户数据泄露,那么攻击者很容易通过 id + password_digest 的hash 来伪造remember_token的?!当然,如果数据库泄露,人家也不用这么麻烦是吧。但可以悄悄做一些恶意的事情。

Abca79

#15楼 @yiming session是存在于cookie的

96

#16楼 @so_zengtao 明白。我指的是攻击者拿到了服务器上的用户数据后可能导致的问题。

96

#16楼 @so_zengtao Anyway, 这几个方法对 cookie 泄露几乎是无力的。所以用户还是得注意保护自己的敏感数据。

此外,值得注意的是:既然做hash,那么请务必不要把hash前的原始数据暴露出来。无论这个数据是在你的服务器上还是在用户的设备里。

1

#13楼 @yiming 如果数据库存 remember_token_digest,似乎支持不了多设备登录?

当然根据不同应用场合有不同的安全级别,目前我做的应用能拿到数据库就已经没什么可偷了。

9442

可以去看下我最新的一篇topic,有用户登录和退出,以及简单的基于用户组的权限控制

96

#19楼 @Rei 对,另一台设备显式 sign in 就会让原先的session失效。你说得没错,需要根据实际应用场景做权衡。BTW, campo是不错的Rails app例子。对我这样的新手很有帮助!希望哪天能给campo提交PR。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册