前言
分布式用户认证, 有个简单的称谓就是单点登陆, 即一处登陆,到处通行.
说详细一点就是,集中的用户统一身份认证和分布的式的用户验证和资源访问控制.
对于小公司而言,提供的服务少,常常用户认证和服务混合在一起,体会不到分布式用户认证好处.
随着公司规模的扩大,提供的服务越来越多,把用户认证和服务提供拆分开来,实现分布式用户认证,可降低系统的相互依赖性,提高系统的可扩展性.
常见的方案
基于普通token的方案.
这个方案通常在用户登录后,把用户信息储存与中心服务器, 同时给客户端一个普通token, 以后访问服务时均以此token识别用户身份. 这个token只是一个hash值,一个唯一的ID,自身不含用户信息,要辨别token的真伪,需要的中心服务器查询,这是一个集中用户认证的方案,简单易用,当可扩展性不高.
本文介绍一个新的方案
基于JSON Web Token(JWT)的方案.
JWT,简单的说就是把用户的公开信息和信息的签名合成一个字符串,保证信息无法伪造.详细可参考互联网上的资料。
JWT 和基于hash值的普通token的主要不同点:
- JWT 自身包含用户的公开信息。
- JWT 不用到中心服务器查询就可验证真伪。
这些特点,使得JWT 很像现实生活中的身份证,签证等证件。
这个方案,通过用户登陆后,中心服务器给客户端一个JWT,这个JWT包含用户的公开信息,还有用户权限等信息。之后,客户端访问服务时,就以这个JWT作为身份识别,而服务提供者,不用到中心服务器查询,自己可校验这个JWT的真伪。
以示范案例说明
以一个社区应用例,功能模块如下:
- 发帖讨论的论坛模块
- 实时通信模块
- 收费的教育视频模块
- 收费的音乐模块
当然,以上四部分都需要用户认证。
这四个模块,通常由四个项目组完成。
作为架构设计者,有两个重要的思想:
- 假设这四个模块,分别由四个独立的公司来开发。
- 每个模块不只我们公司用,其他公司也可用
就是把API或是服务service 当做最终独立的产品来设计,这样就能设计出好的架构.
对于这个系统,我们看看用户认证系统如何设计?
抛开传统的登陆概念,传统的登陆通常只是登陆一个地方,访问一种服务.
当设计认证系统时,不要想我们在设计软件系统,就当在设计一个国家,没错一个虚拟的国家.
看看国家的分布式用户认证是怎么运作的?
以美国为例,移民局负责颁发用户签证,而里面的大学,酒店,企业就是各种服务提供者.
这里用户认证和服务提供是分开的.
要入境美国,首先得像移民局申请签证.
当用户拿着签证去住酒店时,酒店服务员会查看签证的真伪及有效期.
当用户拿着签证去住企业应聘时,企业会查看签证的真伪及有效期,还有就是权限,如果是旅游签证,对不起,旅游签证不能打工.
注意:签证是由移民局集中发行的,而校验确是分布的.
酒店服务员验证签证时,不会打电话到移民局查询真伪.
我们的用户认证系统,其实只要把这一套机制帮过来即可.
由统一的用户认证系统负责颁发签证,而用户访问各种服务时,持有这个签证就可以了.
用户认证后,我们可以把用户的公开信息如user id等,还有就是授权信息,比如6个月的视频教程授权,1个月的音乐授权等写到这个签证上,这样用户就可访问各种服务.
JWT 防伪有两类签名机制,一类是基于secretKey的Hash机制,一类是非对称签名机制.
第一类Hash机制,JWT的创建和验证使用同一个秘钥,仅适合公司内部用.对应开放平台,要开放给其他公司使用,需要采用非对称签名机制,这样创建和校验是两个秘钥,保证token的集中发行.
分布式JWT用户验证的问题.
分布式JWT用户验证的问题的一个问题是,Token 一旦发行,无法注销,只能等其自行失效.
这个不单是JWT的问题,所有可分布式验证的证件都有这个问题,包括身份证,签证,驾照等.
驾照丢了,去管理局注销,但这个注销,不会让丢失的驾照立即失效,除非驾照的验证是集中式的.
这也是为什么几乎所有的证件都有一个有效期的原因.
对应JWT,为了保证安全,我们可以使用一个比较短的有效期,同时采用一种以旧换新的机制,确保安全.
这个机制有点类似生活中的驾照年审或者签证延期,即每隔一段时间做一次审查并核发新证,由于不需要人工操作,我们的这个审查频率提高一些.
Token以旧换新的机制,请参看:
http://www.jianshu.com/p/b4cf771e570e
注:现实生活中,护照和签证有些差别,对于软件系统这个差别就不考虑了,统一当成证明身份的证件.
网友评论