以前接入百度帐号系统的时候写了一篇博客作研究:【大前端】认识单点登陆,出来后才发现,不少小公司其实并无将帐号系统打通,总结一下帐号系统没通的缘由是:html
① 最初设计就没想过身份认证应该作整合前端
② 后续业务中逐渐发现登录系统过多,可是迫于业务压力以及整合复杂度,因而再搁置web
这个就是技术债了,这种基础服务的技术债不及时还,会致使不可忽视的工程问题:数据库
① 帐号系统相关需求愈来愈多(登陆、注册、我的信息管理......),每次都须要从新作跨域
② 用户数据没有一个收口的地方,若是数据量一块儿来要整合、分析就难了(好比一些系统使用帐号登陆、一些系统使用手机登陆,若是想所有改形成以手机登陆就很难作到)服务器
③ 帐号系统不通(全部应用须要共享一个身份认证系统),会致使频道不通问题,好比多数状况下钱包也是一个独立的频道,而一个子频道产生订单后,须要去钱包频道完成支付(http --> https)这个时候若是须要从新登陆的话是十分操蛋的行为cookie
要解决以上问题,就要打通帐号系统,这个有两个必要条件:session
① 全部应用系统都直接依赖与同一套身份认证系统dom
② 全部的子系统都得改造经过上述认证系统认证,也就是以前文章说的,要可以识别ticket数据库设计
而后真实的状况是比较失望的,以前已经有不少子系统各自为政了,并且数据库都不一致,因此更多的时候咱们的问题是:
① 如何实现打通帐号系统
② 新业务如何接入帐号系统
③ 老业务如何接入帐号系统
④ H5应该如何作
⑤ Native应该如何作
⑥ 没时间(没意识)
文中内容皆是自我知识总结,而且我是前端,若是文中有误请您指出。
实现帐号系统打通的前提是用户数据共享,分散的用户管理是帐户系统打通的拦路虎,用户数据不能共用,各个系统之间根本没任何联系,因此要严谨子业务独立建立用户,公司的全部系统必须依赖于同一张用户信息表,这是一张不包含任何业务的表,可能包含如下数据:
① 用户id
② 用户昵称
③ 用户手机
④ 用户密码
⑤ 头像&性别&出生年月&身份证&头像......
比较差的状况是各个子系统的登陆注册彻底独立,这样用户便造成了信息孤岛,将各子系统的用户公共信息迁移到一张表是第一步。
PS:这种各个子系统独立的状况,甚至可能出现用户表中存在重复手机号的状况
若是全部子系统接共用同一张用户表,那么第一个问题立刻就出来了,差别化如何处理,好比:
① 子系统A用户具备角色权限功能,好比管理员、游客、超级管理员
② 子系统B用户用于医院角色,具备职称属性,正教授、副教授、讲师
③ 子系统C为一个医院机构,具备地址、三甲等属性
这个时候须要各个子系统本身维护一个用户角色表,好比这样:
1 //用户总表 2 //公司用户不必定都是子系统的用户,但子系统用户必定存在与公司用户总表中 3 var users = [ 4 { 5 id: '1', 6 phone: '13579246810', 7 name: '昵称1', 8 infos: '其它公共信息' 9 }, 10 { 11 id: '2', 12 phone: '13579246811', 13 name: '昵称2', 14 infos: '其它公共信息' 15 }, 16 { 17 id: '3', 18 phone: '13579246812', 19 name: '昵称3', 20 infos: '其它公共信息' 21 } 22 ]; 23 //子系统A中的用户表 24 var a_users = [ 25 { 26 id: '1', 27 roleId: '1'//游客 28 }, 29 { 30 id: '3', 31 roleId: '2'//超级管理员 32 } 33 ]; 34 //子系统B中的用户表 35 var b_users = [ 36 { 37 id: '1', 38 title: '教授'//游客 39 }, 40 { 41 id: '2', 42 roleId: '副教授'//超级管理员 43 } 44 ]; 45 //子系统C中的用户表 46 var c_users = [ 47 { 48 id: '2', 49 address: 'xxxx', 50 title: '三甲'//游客 51 }, 52 { 53 id: '3', 54 address: 'xxxx', 55 roleId: '二甲'//超级管理员 56 } 57 ];
这个时候不一样的系统差别化就能获得处理。有一种比较很差的状况是,以前子系统用户表中就已经包含了业务信息好比(roleId),这个时候要分离就比较烦了
不少朋友不关注数据库设计的三范式,但真正遇到问题的时候才能深入认识到第三范式能带来什么好处!
用户数据打通后,即可在此基础上进行下一步工做了!!!
全部的passport系统(统一登陆认证系统)核心功能就两个:
① 登陆
② 受权或者鉴权
PS:由于咱们团队暂时全部应用全在一个主域下,就暂时没考虑跨域的状况。
咱们这里的实现方案是这样的:
① 子系统(a.domain.com)访问须要登陆的接口,未登陆则跳到统一登陆页面(passport.domain.com)
② 用户完成登陆后,server端向主域cookie写入ticket,跳回子系统a.domain.com
③ 子系统a.domain.com访问接口,server端发现带有ticket,便去passport服务器校验,成功则返回给子系统server用户id
④ 子系统往本身域名写入cookie,有效时间内再也不走passport鉴权
同理,若是子系统b.domain.com进行系统,由于主域上已经有ticket,便会直接进入a的业务系统,获取和该业务系统相关的权限控制等信息了
这里举个例子,用户调用获取基本信息接口getInfo整个流程:
① 由于接口须要登陆状态,因此先到passport登陆
② passport登陆后往主域cookie种入标志ticket,而且从新跳回子系统
③ 子系统访问getInfo接口,发现主域中具备ticket标志,则拿着这个标志去passport校验,校验成功返回用户信息
④ 子系统根据基础用户信息,拿着用户id将更多的信息筛选出来,好比roleId,返回给前端H5页面
这个便是统一的认证系统,而这里有一个容易被忽略的关键是:
子系统获取主域中的ticket,去passport校验有效性
这句话的意思是,每一个子系统都必须可以识别passport机制的ticket,意思是每一个子系统都必须接入passport
而接入的方式其实很简单,几个步骤就能够作完,好比说:
① passport方提供一个接口,getUserInfo,若是主域中具备cookie信息便能返回用户信息,若是没有就返回错误码(未登陆)
② 业务系统若是须要登陆信息的话,server首次直接根据ticket去passport拿用户信息,若是拿获得就在本地存储session,若是拿不到就直接返回passport的错误码便可
③ 业务系统若是拿到用户信息,能够本身作简单包装,也能够什么都不作,全看业务需求
关于退出登陆,其实比较简单,稍微改下各个业务系统的判断规则,必须ticket在才考虑自己系统的session是否存在,每次退出操做,直接调用passport的登出接口删除主域ticket便可。
更多状况下咱们会有APP使用Webview打开H5页面的状况,这里要作登陆态处理的话,便须要App请求passport接口后保存ticket,当打开webview时直接往主域注入ticket便可。
固然,这里的前提是,子系统已经接入了passport。
关于跨域部分由于实际工做没有碰到暂时不涉及,这里知识点根据后续接入程度可能会作修改。
关于代码的简单实现你们能够看看这篇文章:http://www.cnblogs.com/yexiaochai/p/4422460.html实现大同小异