源于最近各种改版,与PD一直撕逼,感觉对账户业务开悟了,梳理一下。
基础思路
抽象来说,账户业务就两个方面:
- 账户详情:用户相关的所有信息。在客户端系统中,相当于维护了一个分布式(客户端、服务端)的数据存储,核心在同步策略
权限管理:这个就复杂了,内容包括:
- 权限存储:其实是用户详情的一部分,仍然是存储和同步为重点的功能,客户端要求有足够高的性能
- 权限获取:这个其实是小系统上的主要业务,是与用户交互,验证用户身份,补全用户缺失信息和权限的功能部分
- 权限管理:是一个客户端为主的App运行基础服务,整体上应该和Android的权限系统接近。每个业务(Android App)都会对用户权限(Permission)有一定的要求。在启动(安装APK)时,有预授权;在使用权限时,有实时获取(ActivityCompat.requestPermissions)
从整体上看,权限存储和获取是权限管理的底层服务,都是不依赖其他业务逻辑的原子服务。而权限管理是整个账户系统的对外接口,外部可使用的接口应该仅限于运行时申请和运维时的配置。
账户详情
重点在服务端数据同步、客户端性能。
数据同步
同步包含两个方面:
- 充分利用时机:时机来说,包括了客户端事件(登录、登出、升权等),固定间隔的轮询和服务端事件(PC端产生的事件)
- 充分利用信道:一般来说,客户端都会有pull通道和push通道,根据具体信息的特性,选择合适的通道进行增量更新,使用时间戳进行多次更新的去重。例如,在PC端/其他客户端修改比较频繁的信息(收货地址)就比较适合push通道。服务端接收修改时间,直接推送给客户端;而像账号本身,就比较适合pull通道,在登录时间的时候更新
性能
无非就是cache了。层次上(Android)就是 Memory->SharedPreferences->DB->CDN->Server。这里面的门道就超出了业务范围,标准流程就好了。
权限管理
权限管理
作为外部依赖,对外提供两个接口:运行时权限管理和运维时的权限配置。
运行时
运行时的接口,应该是与Android系统权限接口类似。分为check和request,都是以回调形式存在的。
运维时
运维时对应的情景是,配置某个功能进入时就必须有的权限。权限管理在运行时切入各个功能启动点,首先进行权限检测或补全,再进行或跳过功能。
比如,看视频自动跳过片头广告的功能(不要纠结是跳过还是根本不打开广告)。业务功能就是跳过广告,需要的权限是付费VIP,权限管理切面仅检测不补全。如果一个非VIP用户过来,权限管理发现权限失败,直接跳过该功能。
这是一个AOP的思考方式,个人认为,权限本身更多的应该做到AOP而不是嵌入业务内部。
权限存储
权限存储的技术方面跟用户信息是差不多的,只是增加了权限申请后的同步,这里面主要就是要做好防护工作,强权限都要多次校验。
权限分类
按维度
- 用户类:仅和用户相关,包含用户组类的权限,这里的权限包含了很多用户能够影响业务流程的状态。比如说,实名认证、微博上的大V认证、付费VIP等
- 用户设备类:用户在该设备上拥有的权限。这些主要是本地权限,比如指纹、手势;还有登录、支付类的权限等
按时间
- 瞬时类:权限获取一段时间后,会失效。这类权限一般都是危险等级比较高的,不能只依靠客户端校验的。比如支付权限、授权登录权限(授权登录的token)等。还包括了VIP这种会随时间而失去的权限
- 永久类:权限获取后就一直存在。大部分是用户类的权限,比如实名认证
按验证方式
- 校验类:通过用户操作,识别用户身份的一类验证。比如,支付密码、登录密码等
- 补全类:通过用户操作,完善用户信息的一类验证。比如,实名认证、用户等级等;还要包括对校验类功能信息补充。比如补全支付密码等
权限之间有两种关系:
- 依赖关系:B权限的获取要求必须有A权限。例如,想要有VIP权限,必须有登录权限
- 强弱关系:例如,支付权限要强于登录权限
最终设计
服务端
采用最单一功能分割的方式,可以打碎成这些系统:
- 用户信息存储:存储用户信息
- 权限管理配置:配置权限的PC页面,配置信息对接客户端
- 权限获取:提供原子化的权限获取方式,比如登录密码验证,实名认证补全等
- 权限编排:根据权限间的关系和用户状态,返回合理的权限获取方式。对接客户端权限管理
- 权限存储:维护用户、设备的权限,基础服务
客户端
这个就比较简单了:
- 存储:存储基础服务
- 用户详情存储:依赖存储,维护用户详情
- 权限存储:依赖存储,维护用户权限
- 管理存储:依赖存储,维护权限管理的配置
- 权限管理:切面系统
- 权限获取:对接服务端的权限编排和获取,用于提示用户权限