在阅读了这里关于反序列化和序列化用户如何在Passport流中工作的精彩描述之后
了解passport序列化反序列化
我关心的是对每个请求都调用deSerializeUser对性能的影响。我见过的所有示例(见下面的示例)都是deserializeUser调用类似于数据库的内容
我的问题是我是否误解了用例?有没有可能建议对给定网页的每个服务器请求进行数据库类型调用?
如果答案是肯定的,我假设修复这个问题的唯一方法是缓存用户凭据,但从安全角度来看,我通常确实讨厌缓存凭据。
思想?
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.id);
// where is this user.id going? Are we supposed to access this anywhere?
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
一般来说,是的,您希望在数据库中存储用户登录状态/会话,并在每个传入请求中提取/更新它,因为它的容错性要强得多。
假设您没有数据库,将会话存储在Web/App服务器上,并且可能有许多这样的服务器为同一个Website/App提供服务,以处理负载。如果您的一台服务器出现故障,那么由该服务器提供服务的所有用户的所有会话数据都会丢失(这种方法还有一个麻烦--您需要确保一个用户始终由同一个Web/App服务器提供服务,因为他/她的会话存储在该服务器上--因此您需要在负载均衡器上处理会话关联/粘滞会话,这通常是一个麻烦,甚至有些设置是不可能的)。
另一方面,当您在数据库中存储会话时,如果您的一个服务器出现故障,其他服务器可以立即从数据库中检索数据(并且您不需要将用户绑定到特定的服务器)。
您可能会缓存数据,比如使用Redis(或memcached),但是您需要确保缓存不是运行在与您的App/Web相同的服务器上,因为您将面临同样的问题。(Redis可能是一个更好的解决方案,因为如果运行它的节点出现故障,您可以拍摄它的快照并快速恢复它的数据,但使用memcached不能这样做,至少不能直接这样做)
通常,您希望将这类数据存储在能够很好地处理这类流量的DB中(例如Mongo,DynamoDB,Redis),而不是存储在关系数据库中。
关于CND,一般来说,它不会从您的DB(会话存储)中卸载很多流量,因为您可能不想只为每个人提供缓存的静态内容。因此,您仍然需要某种验证,您需要针对您的应用程序服务器发出请求,它仍然会查询DB以检查用户是否被批准请求该静态内容,创建某种签名URL,将其发送到客户端,并且只有在此之后,用户才能从CDN访问受保护的内容(但是,如果配置为这样,您可以重用该签名URL,因此它会有所帮助)。