【发布时间】:2017-01-24 15:28:51
【问题描述】:
我正在对从跨源 ajax 客户端接收的 json Web 令牌进行 Node.js 服务器端验证。据推测,令牌是由Google OpenID Connect 生成的,其中声明如下:
要使用 Google 的 OpenID Connect 服务,您应该将 Discovery-document URI 硬编码到您的应用程序中。您的应用程序获取文档,然后根据需要从中检索端点 URI。
您可以通过缓存 Discovery 文档中的值来避免 HTTP 往返。使用标准 HTTP 缓存标头,应予以尊重。
来源: https://developers.google.com/identity/protocols/OpenIDConnect#discovery
我编写了以下函数,该函数使用 request.js 获取键,并使用 moment.js 将一些时间戳属性添加到我存储缓存键的 keyCache 字典中。该函数在服务器启动时调用。
function cacheWellKnownKeys(uri) {
var openid = 'https://accounts.google.com/.well-known/openid-configuration';
// get the well known config from google
request(openid, function(err, res, body) {
var config = JSON.parse(body);
var jwks_uri = config.jwks_uri;
var timestamp = moment();
// get the public json web keys
request(jwks_uri, function(err, res, body) {
keyCache.keys = JSON.parse(body).keys;
keyCache.lastUpdate = timestamp;
keyCache.timeToLive = timestamp.add(12, 'hours');
});
});
}
成功缓存了密钥之后,我现在关心的是如何随着时间的推移有效地维护缓存。
由于 Google 很少更改其公钥(大约每天一次),因此您可以缓存它们,并且在绝大多数情况下执行本地验证。
来源:https://developers.google.com/identity/protocols/OpenIDConnect#validatinganidtoken
由于 Google 每天都在更改其公钥,我对 keyCache 的 timestamp 和 timeToLive 属性的想法是做以下两件事之一:
- 每 12 小时设置一次超时以更新缓存
- 处理 Google 在我的 12 小时更新周期之间更改其公钥的情况。我端第一次失败的令牌验证会触发密钥缓存的刷新,然后是最后一次尝试验证令牌。
这似乎是一种可行的工作算法,直到我考虑到大量无效令牌请求导致在尝试更新缓存时重复往返于众所周知的配置和公钥。
也许有更好的方法可以减少网络开销。上面第一句话中的这一行可能与开发更有效的解决方案有关,但我不确定该怎么做:Standard HTTP caching headers are used and should be respected.
我想我的问题真的只是这个......
我是否应该利用 Google 发现文档中的 HTTP 缓存标头来开发更高效的缓存解决方案?这将如何运作?
【问题讨论】:
标签: node.js caching google-openid