美文网首页
【大前端之打通账号系统】passport应该如何落地?(来源于网

【大前端之打通账号系统】passport应该如何落地?(来源于网

作者: AllenBan | 来源:发表于2018-08-15 11:37 被阅读111次

    之前接入百度账号系统的时候写了一篇博客做研究:【大前端】认识单点登录,出来后才发现,很多小公司其实并没有将账号系统打通,总结一下账号系统没通的原因是:

    ① 最初设计就没想过身份认证应该做整合

    ② 后续业务中逐渐发现登陆系统过多,但是迫于业务压力以及整合复杂度,于是再搁置

    这个就是技术债了,这种基础服务的技术债不及时还,会导致不可忽视的工程问题:

    ① 账号系统相关需求越来越多(登录、注册、个人信息管理......),每次都需要重新做

    ② 用户数据没有一个收口的地方,如果数据量一起来要整合、分析就难了(比如一些系统使用账号登录、一些系统使用手机登录,如果想全部改造成以手机登录就很难做到)

    ③ 账号系统不通(所有应用需要共享一个身份认证系统),会导致频道不通问题,比如多数情况下钱包也是一个独立的频道,而一个子频道产生订单后,需要去钱包频道完成支付(http --> https)这个时候如果需要重新登录的话是十分操蛋的行为

    要解决以上问题,就要打通账号系统,这个有两个必要条件:

    ① 所有应用系统都直接依赖与同一套身份认证系统

    ② 所有的子系统都得改造通过上述认证系统认证,也就是之前文章说的,要能够识别ticket

    然后真实的情况是比较失望的,之前已经有很多子系统各自为政了,而且数据库都不一致,所以更多的时候我们的问题是:

    ① 如何实现打通账号系统

    ② 新业务如何接入账号系统

    ③ 老业务如何接入账号系统

    ④ H5应该如何做

    ⑤ Native应该如何做

    ⑥ 没时间(没意识)

    文中内容皆是自我知识总结,并且我是前端,如果文中有误请您指出。

    用户数据共享

    实现账号系统打通的前提是用户数据共享,分散的用户管理是账户系统打通的拦路虎,用户数据不能共用,各个系统之间根本没任何联系,所以要严谨子业务独立创建用户,公司的所有系统必须依赖于同一张用户信息表,这是一张不包含任何业务的表,可能包含以下数据:

    ① 用户id

    ② 用户昵称

    ③ 用户手机

    ④ 用户密码

    ⑤ 头像&性别&出生年月&身份证&头像......

    比较差的情况是各个子系统的登录注册完全独立,这样用户便形成了信息孤岛,将各子系统的用户公共信息迁移到一张表是第一步。

    PS:这种各个子系统独立的情况,甚至可能出现用户表中存在重复手机号的情况

    差异化处理

    如果所有子系统接共用同一张用户表,那么第一个问题马上就出来了,差异化如何处理,比如:

    ① 子系统A用户具有角色权限功能,比如管理员、游客、超级管理员

    ② 子系统B用户用于医院角色,具有职称属性,正教授、副教授、讲师

    ③ 子系统C为一个医院机构,具有地址、三甲等属性

    这个时候需要各个子系统自己维护一个用户角色表,比如这样:

    [ 复制代码

    ](javascript:void(0); "复制代码")

    <pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;"> 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 ];</pre>

    [ 复制代码

    ](javascript:void(0); "复制代码")

    这个时候不同的系统差异化就能得到处理。有一种比较不好的情况是,之前子系统用户表中就已经包含了业务信息比如(roleId),这个时候要分离就比较烦了

    <pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">很多朋友不关注数据库设计的三范式,但真正遇到问题的时候才能深刻认识到第三范式能带来什么好处!</pre>

    用户数据打通后,便可在此基础上进行下一步工作了!!!

    统一认证系统

    所有的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的业务系统,获取和该业务系统相关的权限控制等信息了

    image

    这里举个例子,用户调用获取基本信息接口getInfo整个流程:

    ① 因为接口需要登录状态,所以先到passport登录

    ② passport登录后往主域cookie种入标志ticket,并且重新跳回子系统

    ③ 子系统访问getInfo接口,发现主域中具有ticket标志,则拿着这个标志去passport校验,校验成功返回用户信息

    ④ 子系统根据基础用户信息,拿着用户id将更多的信息筛选出来,比如roleId,返回给前端H5页面

    这个即是统一的认证系统,而这里有一个容易被忽略的关键是:

    <pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">子系统获取主域中的ticket,去passport校验有效性</pre>

    这句话的意思是,每个子系统都必须能够识别passport机制的ticket,意思是每个子系统都必须接入passport

    而接入的方式其实很简单,几个步骤就可以做完,比如说:

    ① passport方提供一个接口,getUserInfo,如果主域中具有cookie信息便能返回用户信息,如果没有就返回错误码(未登录)

    ② 业务系统如果需要登录信息的话,server首次直接根据ticket去passport拿用户信息,如果拿得到就在本地存储session,如果拿不到就直接返回passport的错误码即可

    ③ 业务系统如果拿到用户信息,可以自己做简单包装,也可以什么都不做,全看业务需求

    结语

    关于退出登录

    关于退出登录,其实比较简单,稍微改下各个业务系统的判断规则,必须ticket在才考虑本身系统的session是否存在,每次退出操作,直接调用passport的登出接口删除主域ticket即可。

    关于APP与H5鉴权

    更多情况下我们会有APP使用Webview打开H5页面的情况,这里要做登录态处理的话,便需要App请求passport接口后保存ticket,当打开webview时直接往主域注入ticket即可。

    当然,这里的前提是,子系统已经接入了passport。

    关于跨域部分因为实际工作没有碰到暂时不涉及,这里知识点根据后续接入程度可能会做修改。

    关于代码的简单实现大家可以看看这篇文章:http://www.cnblogs.com/yexiaochai/p/4422460.html实现大同小异

    相关文章

      网友评论

          本文标题:【大前端之打通账号系统】passport应该如何落地?(来源于网

          本文链接:https://www.haomeiwen.com/subject/bwgibftx.html