带有 Passport-Local 和 deSerializeUser 问题的简单身份验证 [英] Simple Auth With Passport-Local and deSerializeUser problem

查看:43
本文介绍了带有 Passport-Local 和 deSerializeUser 问题的简单身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读这里关于如何在 Passport 流程中反序列化和序列化用户的出色描述后

After reading an excellent description here on how deserialize and serialize user works in the Passport flow

了解护照序列化反序列化

我担心对每个请求都调用 deSerializeUser 对性能的影响.我见过的所有示例(见下文)都有 deserializeUser 调用看起来像数据库 User.findById 来完成这项工作.假设您没有为所有资产使用 CDN,这意味着每次页面加载时都会调用许多数据库.

I'm concerned about the performance impact of having deSerializeUser called on every request. All the examples I've seen (see below for one) have deserializeUser calling what looks like a database User.findById to do that work. Assuming you are not using a cdn for all your assets, that means many many database calls on every page load.

我的问题是我是否以某种方式误解了用例?是否可能建议对给定网页的每个请求进行数据库类型调用?

My questions is am I mis-understanding the use case somehow? Is it possible that it is being recommended to make a database type call on every request into a server for a given web page?

如果答案是肯定的,我认为解决此问题的唯一方法是缓存用户凭据,但从安全角度来看,我真的很讨厌缓存凭据.

If the answer is yes, I assume the only way to fix this is to cache the user credentials, but from a security perspective, I really hate to cache credentials in general.

想法?

// 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);
    });
});

推荐答案

一般来说,是的,您希望将用户登录状态/会话存储在数据库中,并随着每个传入请求获取/更新它,因为它具有更高的容错性.

In general, yes, you want to store user login state/session in database and fetch/update it with each incoming request as it is much more fault tolerant.

假设您没有数据库并且您将会话存储在您的网络/应用程序服务器上,并且可能有许多此类服务器为同一网站/应用程序提供服务来处理负载.如果您的一个服务器出现故障,则该服务器提供的所有用户的所有会话数据都将丢失(这种方法还有另一个麻烦 - 您需要确保一个用户由同一个 Web/应用程序服务器提供服务)他/她的会话存储在该服务器上的时间 - 因此您需要以某种方式处理负载均衡器上的会话亲和性/粘性会话,这通常很痛苦,有些设置甚至是不可能的).

Assume that you don't have a database and you are storing the session on your web/app server and there might be many such servers serving the same website/app to handle the load. If one of your server fails, all your session data for all users that were served by that server is lost (there is yet another hassle with this approach - you need to make sure that one user is served by the same web/app server all the time as his/hers session is stored on that server - so you need to somehow handle session affinity/sticky sessions on your load balancer which is usually a pain, even impossible is some setups).

另一方面,当您在数据库中存储会话时,如果您的服务器出现故障,其他服务器可以立即从数据库中检索数据(并且您不需要将用户绑定到特定服务器).

On the other hand, when you are storing sessions in a database, if one your servers fail, the data can be immediately retrieved by other servers from the DB (and you don't need to bind user to a particular server).

您可以缓存数据,比如说使用 Redis(或 memcached),但是您需要确保缓存与您的应用程序/网络不在同一台服务器上运行,因为您将面临同样的问题.(Redis 在这里可能是一个更好的解决方案,因为您可以拍摄它的快照并在运行它的节点失败时快速恢复其数据,您不能使用 memcached 做到这一点,至少不能直接做到这一点)

You may cache the data, let's say using Redis (or memcached), but then you need to make sure that the cache is not running on the same server as you app/web because you will face the same problem. (Redis is probably a better solution here as you can take a snapshot of it and quickly restore its data if node running it fails, you can't do that with memcached, at least not directly)

通常,您希望将此类数据存储在可以很好地处理此类流量的数据库中(例如 Mongo、DynamoDB、Redis),而不是存储在关系数据库中.

Generally, you want to store this kind of data in a DB that can handle this type of traffic well (eg. Mongo, DynamoDB, Redis) not in a relational database.

关于 CND,一般来说,它不会从您的数据库(会话存储)卸载大量流量,因为您可能不希望仅向所有人提供缓存的静态内容.因此,您仍然需要某种验证,您需要针对您的应用服务器发出请求,该服务器仍将查询数据库以检查用户是否被批准请求该静态内容,创建某种签名 URL,将其发送到客户端,只有在此之后,用户才能从 CDN 访问受保护的内容(但如果配置如此,您可以重复使用该签名 URL,因此它会有所帮助).

About the CND, in general, it will not offload much of the traffic from your DB (session storage) as you probably don't want to serve cached static content to just everyone. So you still need some kind of verification for which you need to make a request against your app server which will still query the DB to check whether a user is approved to request that static content, create a some kind of signed URL, send it to client and only after that the user can access the protected content from the CDN (but you can reuse that signed url if configured so, therefore it can help a bit).

这篇关于带有 Passport-Local 和 deSerializeUser 问题的简单身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆