Web 安全登录

基本解决方案

绝大多数Web应用里面都有用户登录的功能。

由于HTTP(S)协议的特点,服务器没有办法锁定客户端,因为客户端对服务器发送HTTP(S)请求的时候,往往没有携带自身的信息,于是服务器想确认客户端的身份是有心无力的。

于是出现了在HTTP(S)报头中附带Cookie的一种做法,来帮助服务器识别客户端:

Created with Raphaël 2.1.0 客户端 客户端 服务器 服务器 没有携带Cookie 初次访问 你这厮没有Cookie?我给你生成一个 响应并要求客户端存储给定Cookie 有了Cookie 携带Cookie访问一些需要登录才能查看的资源 查表发现这个Cookie没有与任何用户的联系说明还没登录! 提示需要登录的响应 登录 携带Cookie、用户凭证发送登录请求 记下了这个Cookie与XXX的暂时的联系 登录成功! 有了登记后的Cookie 携带Cookie访问一些需要登录才能查看的资源 查了之前维护的联系表,确认这个Cookie对应的用户是XXX 正确回复资源。

这就是Web应用处理用户登录的解决方案。

Cookie是储存在用户的浏览器中的,通常还会带有一个域名:这个Cookie是哪个网站要求设置的

比如百度设定Cookie就有存储在www.baidu.com这个域名中,当你访问这个域名的时候,浏览器就会自动在HTTP(S)的请求报头中附上对应的Cookie,避免了不同网站之间Cookie的命名空间冲突。

安全与性能

现在问题来了,怎么在Cookie中存储一些信息比较好呢?

不妨先给出几个分析:

  • Cookie 不宜过大。
    由于Cookie会附到每一次HTTP(S)请求中,若Cookie过多,会明显增重网络I/O的负担。
  • Cookie 不宜可读
    由于Cookie在客户端本地可以很方便地被JavaScript修改,若Cookie可读,那么也很容易被恶意用户篡改(伪造)
  • Cookie 不宜与用户信息有关
    如果Cookie的生成与用户的信息有关,即便Cookie加密到不可读,一旦算法被识破,就有一定几率被反推伪造,或者泄漏个人信息,有隐患。

由此我们可以有这样一个解决方案:

  1. 当用户访问时,随机生成一个足够强的Hash值作为Cookie,跟用户信息无关、且不可读、不易伪造。
  2. 在后端服务器维护一个以上述Hash值作为索引的集合。
  3. 在上述集合中缓存用户的个人信息。
  4. 当用户访问需要验证身份的资源时,服务器从集合中取出对应的Cookie,并检查缓存中的个人信息来确认身份。
  5. 当用户修改了个人信息时,更新缓存。

这个Hash值就相当于一个口令,通常我们称它为Session ID(会话ID)。意思就是维护一个客户端与服务器之间的会话,用一个足够离散的Hash值来防止撞表,通常来说,一个站点同时有效的会话数不超过其用户数的20%,而若Hash值的字符集是64,长度为40,Hash值有 6440=2240=1.81074 种可能,撞表成功的期望代价很高,可以认为是安全的。

万一这个人运气很好,撞表成功了,这意味着他能伪装成某个用户了,这跟暴力破解密码的行为是一致的,但这个SessionID是临时性的,随时可能失效,至少不会造成密码泄露(当然你不能在你的数据库中明文存储用户的密码或者提供API查询密码),当用户选择登出或者Session过期的时候,这个SessionID就会失效,撞表的结果就失去了意义。

关于中间人攻击,一般的做法是加密Cookie,最好使用HTTPS整个加密,这个不属于本文讨论范畴。

另外,这个Session ID确实足够短又足够好用,既不会给网络I/O造成什么严重的负担,也足够服务器来识别用户的身份。

困难的地方在于,设计一个安全的Hash算法是不容易的,没有足够好的数学功底就不要自己写Hash了。直接用现成的算法即可。除此之外,管理Session集合的内存也是不容易的,要正确地增删改Session对象,及时地释放空间……这其实是一个数据结构问题,考虑到查询性能等种种原因,也用别人已经开发好的比较好。

成熟的解决方案

Java Servlet 有 JSessionID 的设置,PHP也有PHPSessionID,NodeJS比较开放,Express有一个插件叫做express-session 可以解决这个问题。

网上学 Session 的资料很多,在此不一一列举,只是想说明为什么要这样实现登录功能。怎么做是安全高效的以及为什么。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值