我正在使用Owin Oauth2开发单页面应用程序(AngularJS + .Net MVC Json Rest API)的身份验证流程(授权和资源服务器是相同的)。
我已经在传统的cookie +会话中选择了Bearer Token路由,因为我希望保持无状态,并且因为移动应用程序将使用相同的Api,其中令牌的问题少于cookie。
这是简化的流程:
AccessToken
,其中包含声明
生成的GUID(代表会话ID)和其他一些声明。 RefreshToken
。 RefreshToken
表中创建一个条目,其中包含以下字段:GUID(PK)| RefreshToken |票务| DateIssued | DateExpire | DateEnd
服务器同时提供AccessToken
和。{1}}
RefreshToken
给客户。
客户端将AccessToken
和RefreshToken
存储到SessionStorage中。
客户使用AccessToken
访问Api。
当AngularJS检测到AccessToken即将到期时,它会缓冲所有请求并发出grant_type refresh_token request
;
服务器使用客户端提供的RefreshToken
并且:
DateExpire > GetTime() And DateEnd is Null
)RefreshToken
和新故障单更新数据库条目(注意:GUID保持不变)当客户端点击注销服务器端时,从记录用户的身份声明中读取的GUID用于使表中的条目无效(DateEnd = GetTime()
)。
客户端的两个令牌都从SessionStorage
中删除。
通过这种方式,我可以撤销RefreshToken
拒绝任何其他请求以获得新的AccessToken
。
这种方法的问题在于,授权被撤销时有一个时间窗口(即:RefreshToken
在DB上失效)但AccessToken
仍然有效(尽管对于有限的框架)时间)。
我想要做的是检查每个请求上AccessToken
的有效性,从用户身份声明中获取GUID并点击数据库以检查该特定GUID的刷新令牌仍然有效。
尽管使查询执行O(1)非常简单,但单点故障本身可能会对系统的可扩展性和性能产生负面影响。
您是否知道另一种缓解此问题的方法?您认为我的方法有任何缺陷吗?
答案 0 :(得分:8)
您的方法没有任何问题,它与我之前的blogged方法完全相同,但我建议您在发送访问令牌时不进行任何数据库检查。
为什么不发布短期访问令牌,即(30分钟),并等到撤销刷新令牌后访问令牌生存时间到期。在客户端上,您可以从客户端本地存储中清除刷新令牌和访问令牌。