浏览器主流授权模式采用Session模式。
JWT全称为:JSON Web Token。适合分布式的授权模式。用户登录成功后,认证服务器会返回一个带有签名认证的JWT。JWT保存在客户端(如浏览器或APP),每次访问应用服务器时,将JWT放到http的header里面。不同于Session的集中管理,JWT自身就包含了用户信息,每台应用服务器可以自己独自判断JWT是哪个用户、是否合法、是否过期,无需再向认证服务器确认,也没有Session同步的问题。JWT至少包含以下信息:
Access Token需要放到http的header里面,用于访问各种资源。由于使用频繁且使用场景复杂,泄露风险较大,因此过期时间会比较短,比如30分钟。如果每30分钟让用户重新登录一次,显然用户体验极差。所以认证服务器在返回Access Token时,还会同时返回一个Refresh Token。Refresh Token平时不使用,只用于从认证服务器获取新的Access Token,会安全很多。
Refresh Token的有效期通常为30天。但在很多手机APP应用,并不想让用户每30天就登录一次。而将有效期设置为1年甚至2年,又觉风险稍大。
给Refresh Token增加一个认证有效期
(如30天),有效期
则可以较长(如1年)。只要在认证有效期
内刷新,则可以获取新的Refresh Token,认证有效期
重新计算,有效期
按前一个Refresh Token计算;如果过了认证有效期
再刷新,则Refresh Token不刷新,且只能获取到Remember Me
权限的Access Token。
只要用户在30天内使用了APP,则自动刷新Refresh Token,无需再次登录。直到1年后刷新有效期到期,才需要再次登录。
刷新Access Token时,自动返回新的Refresh Token。无需专门刷新Refresh Token。
并且在浏览网站时,通常会有两个级别的权限,一种是记住我
的权限,一种是登录
的权限。
给Access Token增加Remember Me
标识。如果Refresh Token过了认证有效期
再刷新,则只能获取到Remember Me
权限的Access Token。
使用浏览器访问时,不能长期保存Refresh Token(安全考虑)。必须在浏览器关闭或用户退出时删除Refresh Token。
要模拟Session 30分钟过期的模式,可以规定在浏览器访问时,返回的Refresh Token的认证有效期为30分钟,用户操作后再刷新Refresh Token,以维持Refresh Token的有效性。
Refresh Token可以保存到Cookie或者sessionStorage,确保关闭页面时Refresh Token会被删除。
可以每5分钟自动刷新Token(不需要自动过期时)。如果需要自动过期,则要根据用户的操作刷新。用户每次操作时,如距离上次刷新Token时间超过5分钟,则自动刷新Token。
每5分钟刷新一次Token,可以更准确的监测在线人数,也更满足模拟自动过期的要求。如果觉得5分钟太短,可以尝试10分钟。
为了避免用户正在操作的时候,突然Refresh Token到期重新登录,应该在Refresh Token到期的最后30天中,用户重新打开APP时,要求用户重新登录。
如果需要监控在线人数,则认证服务器应该将登录的数据写入数据库。由于Access Token的有效期很短,通常需要5分钟到应用服务器刷新一次。因此可以很容易的监控到当前的在线人员。
如何将众多的Access Token和Refresh Token与某个用户的登录关联起来,关键在于用户登录时需要产生一个登录ID
,将这个ID写入所有后续的Refresh Token和Access Token中,则可以知道任意一个Token是属于哪个用户的哪次登录。
由于同一系列的Refresh Token都拥有同一个登录ID,而每个Refresh Token都会在5分钟或者更长的时间内刷新Access Token,因此只要有相同登录ID
的Refresh Token在5分钟内刷新了两次Access Token,就可判顶Refresh Token已经泄露。
Refresh Token强制下线:需要在认证服务器记录所有已发布并在刷新有效期内的Refresh Token(可以只记录登录ID
),每次刷新token时,检查登录ID
是否被强制下线。由于Refresh Token每5分钟刷新一次,且Access Token有效期为30分钟,这种下线不是即时生效的。但代价较低,只要在认证服务器处理即可。
Access Token强制下线:时效性高,立即下线,但代价也较高。需要每个应用服务器在验证JWT时,向认证服务器进行校验,以检查Access Token对应的登录ID
是否被强制下线。这已经违反了JWT自描述的设计初衷,且性能损耗有可能非常大。不过在认证服务器和应用服务器为同一服务器的情况下,还是可用的。
主要用于第三方登录,如微信登录、QQ登录、微博登录等。所有的应用都必须先到认证服务器备案(如微信、QQ、微博),获取客户端ID(Client ID)和客户端密钥(Client Secret)。