多平台的网站实现单点登陆系统(SSO)的开发思路 让你的会员中心更加统一(参考资料)

单点登陆并非一个新鲜的玩意儿,比较官方的解释是企业业务整合的解决方案之一,通俗来说SSO就是一个通用的用户中心,国内比较流行的UCenter就是一套单点登陆解决方案。而近期以CSDN明文存储用户密码并泄露用户信息开始的各大网站争先恐后的泄露本身的用户数据库除了暴露了这些网站的良心和智商外,如何设计用户中心已成为架构师们的热点话题之一。在最近一两年的项目经验中有幸接触到各类平台的单点登陆系统的开发,因此借此机会总结下B/S架构的单点登陆系统的开发经验。javascript

单点登陆系统的类别

就目前比较流行的应用来看,单点登陆系统主要分为三种类型:一种是基于oauth协议的网络令牌(我是这么叫的),一种是基于Web Service或者简单Http协议实现的Passport机制,还有一种是以openid框架造成的通用帐号登陆机制。其中,基于oauth协议主要应用在网站外部,比较知名的有Google Account、Facebook Connect和新浪微博连接等;Passport的应用主要是针对同一网站内不一样架构不一样平台,知名产品则更是数不胜数,例如Google Account帐号基本上能够应用所有Google的网站,而国内各大门户无数的应用系统也都只须要一个用户通行证就能畅通无阻;至于OpenID这样会共享用户信息的应用,在国外可能会很火,在国内这样一个用户一寸金的利益集团面前可能会被采纳,因此下面的论述也主要针对前面两种。html

单点登陆系统的优势

对于用户来说,最理想的状况下一个帐号和密码就能够横行整个互联网,固然这是不可能的。不过现实中稍微有点价值的网站基本上均可以支持各类oauth协议的单点登陆系统,因此能使用微博帐号、SNS帐号或者豆瓣帐号登录的将会为用户带来更多的方便。java

对于企业来说,尤为是业务繁琐复杂的大企业,单点登陆系统可让他们没必要为每个应用都开发用户系统,从而大大下降了工做量,并且统一的用户数据在后期管理和维护中也会更加方便。而基于oauth协议的单点登陆系统虽然开发成本高昂,可是能为企业带来最具备价值的第一手用户信息,其收益可观。jquery

单点登陆系统的基本流程

单点登陆系统(SSO)功能流程图

如上图所示,不论是哪一种方式的SSO系统其功能流程大概都是这样:应用系统只须要调用SSO的验证接口验证当前用户是否为已登陆用户,若是是未登陆用户或者严重不合法则跳转到SSO系统。此时已注册用户能够直在SSO成功登陆后返回应用系统,应用系统开始重复上述步骤;而未注册用户则须要先注册或者使用第三方SSO初始化帐号,继而重复上述步骤。ajax

不一样的是,帐号连接这样的SSO系统在登录成功后返回给应用系统一个key值、用户uid和其余信息,而应用系统通常仍是须要在本身的用户系统中新建一个用户帐户而且创建一个映射关系来关联SSO系统的返回值。以下图所示是实现绑定微博帐号登录的数据库模型图,其中应App_Users表能够实现一个用户绑定多个单点登陆帐号,而且这样的用户是不须要再应用系统中存储密码等没必要要的信息的。而Passport机制的SSO系统基本上处理全部用户登陆、注册、验证的行为,其余应用系统只须要按需取用便可。算法

微博登陆功能的数据库模型

单点登陆系统开发难点

从上述功能流程能够看出,使用基于oauth协议的单点登陆系统应该是比较好的解决方案,可是没有谁愿意把用户的掌控权拱手让给别人,因此国内不少中小网站就算是没有能力开发本身的passport单点登陆系统,也会去选择UCenter这样第三方开源的单点登陆系统。而Passport机制的单点登陆系统都会面临这么一个问题,如何跨域传递cookies,至于为何使用cookies、为何要跨域这么啰嗦的废话我就很少写了,经常使用的跨域传递cookies的方法有三种:javascript/iframe、header和借助数据库。数据库

javascript/iframe的思路是将单点登陆种下的cookie动态传到应用系统,在ajax/jquery普遍应用的时代javascript的是很常见的解决方案,例如UCenter的作法就是在单点登陆系统登录后使用一段javascript动态把cookie传递到全部设置为同步登陆的应用,而iframe由于存在诸多弊端不建议使用。跨域

header的解决方法是使用P3P机制进行跨域传输,可是IE必须用加P3P的头信息才能够跨域。看来IE对跨域的限制更为严格!因此要想实现彻底跨域,在header头里面加上这一句话最好:header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA div COM NAV OTC NOI DSP COR"');。不过在之前使用P3P协议开发单点登陆系统的时候或多或少都有些莫名其妙的问题,看来仍是掌握的太少了。cookie

数据库存储,仍是以Ucenter为例,在Discuz的cdb_sessions表就是一个结合session实现的跨域传递session的功能,只不过这样的功能会给数据库带来严重的I/O负担,但凡是有点流量再碰上点极品的用户这样的数据库性能确定要被严重拖累。网络

在我实际开发过程当中,通常这样解决单点登陆系统的跨域传递cookie问题:首先验证用户来源是否在咱们的站点列表内(若是是首先进入SSO则略去这一步),其次验证用户合法性,用户经过验证后,加密cookie和公用密钥后的值将会在用户登陆以后做为参数一块儿跳转回来来源的应用系统,应用系统获取到cookie值后调用SSO接口进行解密、验证等工做。此外,还有一种比较简略的SSO设计方案,全部SSO系统应有的功能都以API形式呈现,接受被受权的应用系统的请求而且返回相应的XML或者Json结果,不一样的是,这样作须要应用系统最起码的有本身的登录和注册页面,适用于同步不得不使用本身用户功能的已经成型的外部应用系统。

此外,在上一篇文章中讨论过的用户密码加密问题,由上图也能够看出,pass字段存储的应该是用户真正的密码通过md5和加上salt值(随机字符串)再次md5,也就是md5(md5(realpass).salt),这个是程序猿应该知道的最基础的加密方式。此外,不少人容易忽略的一个地方是cookie校验,至少我亲身体验了京东修改完用户密码之前种下的cookie依然可使用,Firebug看了下京东存储的Cookie虽然是加密的,可是明显的验证cookie只是验证了cookie是否为空或者是否能够解密,而彻底没有去验证cookie用户是否合法,这样若是知道了京东的加密算法,即使是不知道用户密码,也能够伪造用户cookie进入用户帐户。

至于网上不少企业给出的SSO解决方案,我就不喷了,MD,若是真要用,UCenter或者简单的使用新浪、腾讯、豆瓣的网站连接都不错,虽然UCenter问题不少(这个之后再喷),可是最起码的企业对用户具备彻底的掌控权。

http://www.itokit.com/2012/0523/74123.html

相关文章
相关标签/搜索