分布式认证

Distributed Authentication

我想实现一种特定的架构,将我的其余部分 API 与将用作不可知模板引擎(例如 DustJS)的 Web 服务器分离。我的后端 API 将使用服务堆栈构建。

我喜欢服务堆栈和 NodeJS 的主要一点是它们都提供了一种身份验证方式,但我只需要一种集中方式来访问凭据以授予对 API 调用的访问权限以及限制某些内容对我的看法。

我想开发的应用程序是一个基于订阅的约会网站,所以这给我带来了一些问题。涉及的参数有roles、groups、authenticate和authorize。在服务堆栈上很容易实现,但我主要对前端如何访问该信息感到困惑。

我如何实现这样一种场景,即前端只检索一次凭据,而不必继续进行 API 调用来检查数据库或缓存以查看是否已检出?我是否需要实施不同的方法来处理希望保持登录状态的客户,或者通常只需设置时间戳值即可解决?

感谢大家的抽空。

你必须检查一些东西。您的网站可能会与客户端建立一个 cookie,每次客户端访问时,它都可以在数据库中检查 cookie 是否有效,但这可能是浪费,因为一个小时内访问该网站的最大唯一用户数可能非常多与总订阅列表相比较小,为了举例起见,假设为 1%。因此,您可以只使用一个 HASH 内存缓存来检查 cookie 会话 ID,如果您喜欢这种额外的安全性,则可以选择使用客户端的 IP 地址。因此,使用会话 ID 和可选的 IP 来查找数据,并确保将上次访问时间存储在数据中,以便在太长时间未访问时使该内存缓存条目无效,或者您可以对其进行垃圾收集,并存储您实际需要的任何其他数据,以实际执行您需要执行的任何其他操作。

如果您的网站变大并扩展到负载平衡集群中的许多计算机,您可以根据客户端 IP 对服务器进行负载平衡,这意味着此缓存不会变得不必要地大,因为通常给定的客户端会访问相同的服务器服务器,但如果他们切换,那很好,因为您的 Web 应用程序可以回退到从数据库加载。

会话只是存储在缓存中的 AuthUserSession POCO

身份验证在 ServiceStack(以及大多数 Web 框架)中的工作方式是,当用户成功身份验证时,一个 Authenticated UserSession is created for that User and stored in the registered Caching Provider you've registered in ServiceStack's AppHost. The session id for that the Authenticated UserSession (aka AuthUserSession) is then stored in the Users cookies under the ss-id Temporary and ss-pid Permanent cookies。

在每次请求时重新发送会话 Cookie

根据设计,Cookie 会在对该域的每个后续请求中重新发送,这就是服务器框架通过简单地从缓存提供程序检索 AuthUserSession 来知道哪个经过身份验证的用户发出每个请求的方式 stored under the following key:

urn:iauthsession:{sessionId}

其中 {sessionId} 是临时 (ss-id) 或永久 (ss-pid) cookie,具体取决于用户是否使用 ?RememberMe=true 进行身份验证。这也意味着您的节点服务器也可以通过使用上述密钥格式访问相同的缓存来轻松访问使用 ServiceStack 进行身份验证的用户会话。

大多数缓存提供程序是分布式的

除了 MemoryCacheClient(默认)之外的所有 Caching providers 都是分布式的,这意味着您的每个负载平衡应用服务器自然能够判断用户是否已通过身份验证。

访问用户会话非常便宜

我不关心检索 UserSession 的性能,因为访问用户会话只需要一次缓存命中就可以通过单个键访问斑点用户会话——这最接近您的服务器可以进行的最便宜的网络请求做。

可以使用直写缓存避免网络请求

避免单个缓存请求检索用户会话的一种方法是使用直写缓存,当用户通过身份验证时,它会保存在本地 MemoryCacheClient 和分布式 ICacheClient (e.g. Redis) 这样,当请求用户会话时,它首先查看本地缓存,如果它不存在,将调用分布式缓存来获取它,在返回之前将其存储在本地缓存中它。您需要注意的一件事是将对分布式缓存的任何更改与存储在所有负载均衡应用程序服务器内存中的本地缓存同步,您可以使用 Redis Pub/Sub 之类的东西在所有应用程序服务器之间发送消息不同的应用服务器。

据我所知 JWT 可以解决您的问题。由于 JWT 令牌不是不透明的,您可以在本地从它的有效负载进行任何类型的验证,而无需检查中央会话服务。

不是太直白,但是说的简单点:"It solved all our problems with sessions"

Auth0 提供了很多关于它的好读物。开始 here.