使用AuthToken架构保护用户帐号验证Cookie的安全性

在项目或者网站开发中,我们很多人很多时候喜欢使用微软的FormsAuthentication类的GetAuthCookie函数生成需要在访客客户端放置的帐号校验Cookie,这个本身没问题,但是很多人会被GetAuthCookie的userName参数误导,以为传递UserID或者UserName就很安全了.而实际上,Cookie本身并不安全,如果完整复制了校验Cookie,在Cookie的允许时间范围内,黑客完全可以使用该Cookie代表的帐号做各种危害网站和应用的事情,即使设定了Cookie的过期时间,但是如果完整复制该Cookie信息,由于站点的machineKey基本不会变化,每次基于特定用户的UserID和UserName生成的Cookie实际上一直不变,那么黑客只要保留了该全部Cookie的信息,就可以一直为所欲为,不受用户登录帐号和密码变更限制,比如校内曾经发生过xss脚本注入事件,导致很多用户丢失了日记照片.所以保护帐号校验Cookie很重要.

 

解决方案是避免使用UserID和UserName这种不会变化的字段做为验证Cookie的基础,我建议使用一种我称之为AuthToken的机制,意即验证Token,(token:标志,象征),AuthToken可以随每次用户通过登录页面登录变化,保证用户的顺畅使用,同时又避免无限期使用不变的验证Cookie导致的帐号被盗现象的发生.

 

下面来解释下AuthToken的运作模式,先上数据库设计图,大家看图理解.

 

 

这张表的字段分别是

UserID:用户标识

AuthToken:验证Token

SessionID:客户端SessionID

ExpireTime:绝对过期时间

 

请注意UserID和AuthToken为合并主键,这并不是错误,而是有意的设计,大家听我解释

首先每个客户端的浏览器我们都会获得一个SessionID,这个是肯定有的,而且同一台机器不同浏览器生成的sessionID也是不同的,sessionID的解释大家看维基百科http://en.wikipedia.org/wiki/Session_ID

然后服务器首先基于回话的SessionID检查用户的客户端是否有AuthToken,如果没有,那很好,用户还没有登录;如果有,那么检查ExpireDate是否过期,如果过期,那么用户需要再次登陆.因为是基于SessionID的判断,所以不同客户端和不同的浏览器生成的sessionID都是不同的,同时因为UserID和AuthToken都为主键,所以可以针对同一个帐号分别设置登录过期时间,比如你在网吧上网,使用的是网站默认设置的20分钟过期时间,在家里设置的是2个星期不用登陆,在单位设置的是3天内不用登陆,虽然Cookie是按照你的设置到期自动清除处理的,但是如果黑客保留住了你全部的Cookie信息,在以往的架构里,设置多长时间对黑客都是没用的,但是在AuthToken架构里,Cookie和数据库的记录对应,所以安全性大大增加,即使黑客保留了你全部的Cookie信息,但是因为数据库中记录了特定的AuthToken的过期时间,而且和SessionID对应,就算挠破了头,黑客也是没有办法使用你的帐号的,这个要安全多了.

另外,如果担心对数据库的压力,可考虑memcached等等的缓存逻辑降低请求量.

posted @ 2011-02-21 00:29  Hex  阅读(8792)  评论(5编辑  收藏  举报