rails 注册登录

July 24, 2014

这几天在做一个小型的论坛,做到了注册登录这一块。之前没有完整做过注册登录这个东西,这次我打算从头写到尾去详细的了解里面的一些基本原理。所以这次并没有使用devise这样的 *gem*。

密码存储

用户密码安全存储是作为一个 web 开发者的基本节操。好在现有的一些解决方案已经能比较好的解决这个问题了,做起来也比较容易。只需要了解一些基本的安全常识就可以保证90%的情况下是安全的。 在数据库里面存储加密后的密文是为了防止被拖库,如果黑客拖下了整个用户表,加密后的密码他们拿着也是没有用的。即使是网站的管理员也是没法知道这个密码的真实原文。因为现在一般的密码 hash 算法是不可逆的。所以现在的一些比较常用的密码明文获取方式是进行字典暴力破解。如果在密码原文 hash 前给密码添加一些比较长的唯一的随机字符串,这会使攻击者的字典基本上失效(因为很长,枚举次数要上升很大一个数量级)。这就是密码加盐(salt)的基本作用。当然加盐的另外一个作用是让两个相同的密码产生不同的 hash 值。这样即使知道加密算法和加密后的密文也无法通过比较密文来得到原文。 在用户登录时我们会拿到用户的原始密码,这个原始密码相当于一把钥匙。拿着这个密码通过加密算法和数据库里面的 salt 得到加密后的密文。再用这串密文与数据库的密文进行比对,比对成功后则验证通过。在这样一个过程中,密码看起来就像打开箱子的钥匙一样,由用户携带,网站不进行存储。

cookie 是存储在用户浏览器中的一段唯一标识,http request 会将它传送到服务端。现在一般的 web framework 会去检测用户的 http request 是否带有 cookie, 如果没有发现请求中没有 *cookie*,它会建立一个*session*。并且以 cookie 作为 key 来保存 *session*。这样如果用户下次同样 cookiehttp request 进来了,就可以找到相同的 *session*。 sessioncookie 是实现记住用户的基石。http 协议是无状态的协议。在用户登录某一个网站后,我们是需要记住登录状态的。这时候就要通过 cookiesession 来干这件事情。 rails 默认是已经将 session 建立好了。在 controller 中可以很方便的拿到 session 变量去存储一些信息。另外比较有意思的是 rails 默认是将 session 经过加密后存储在用户 cookie 中的。当用户的 cookie 传送到后端时会将 cookie 进行解密得到相应的 *session*。