繁体   English   中英

如何正确使用Passport.js?

[英]How to properly use Passport.js?

我在用 :

  • Node.js的
  • 快递4.0
  • Passport.js
  • Google OAuth 2用于身份验证

对于每个用户,我存储在MySQL数据库中(我没有关于此技术的选择)来自他的Google个人资料(电子邮件等...)的一些信息,访问和刷新令牌,以及用户提供的附加信息。他在我的应用程序上注册。

我已经看到了passport.js的不同用途,特别是关于如何在会话中存储该信息。

  1. passport.js的配置页面上 ,我真的不明白以下代码块的要点:

     passport.deserializeUser(function(id, done) { User.findById(id, function(err, user) { done(err, user); }); }); 

    基本上,每次用户发出请求或访问页面时,都会向DB请求并检索信息。 有什么意义? 它减慢了应用程序的速度。 在调用serializeUser时(即,当信息存储在会话中时),不应该检索来自DB的信息吗?

  2. 我已经读过在session中存储太多信息session降低应用程序的速度。 什么是“太多”? 应用程序会减慢多少钱? 有人知道某处是否有测试? 我的应用程序页面需要一组关于我的用户的不同数据(例如,主页只需要他的名字,而个人资料页面将需要所有内容,另一个页面需要知道他拥有的汽车等...)。 passport.authenticate检查用户是否存在于数据库中时,我是否应该将所有信息存储在session中(从而将对数据库的读取请求限制为大约一个),或者仅在会话中存储他的ID并让我的页面向该用户发出附加请求。 DB有必要吗?

  3. 我的另一个问题是:在注册过程中,我首先让用户登录他的Google帐户,我将他的个人资料的详细信息存储在某个地方 ,让他填写表格以获取其他信息,然后我将所有内容都插入到数据库中。 问题是我不知道如何正确存储他的Google帐户详细信息,直到它们插入数据库。 目前,我将它们存储在session ,然后在插入成功时删除它。 更具体地说,当我的数据库中没有找到现有用户时,我会在我的passport.authenticate回调中找到:

     return done(null,false,userInfo); 

    因此,用户未经过身份验证,我有两个问题:我必须将userInfo存储在某处,直到用户注册为止,我必须在注册完成后使用req.login() “手动”登录。

    我是否应该在登录Google帐户后立即对其进行身份验证? 如果他没有完成注册,这不会给我带来安全问题吗?

  4. 最后,我读过有关使用Reddis的内容。 这会帮助我解决这些问题吗?

非常感谢你 !

1)serializeUser过滤数据并将其存储在会话cookie中。 如果可以,通常在cookie中存储较少。 无论如何,您将调用数据库以获取有关用户的数据,因此您只需存储用于检索和重新构建用户的ID,如deserializeUser中所示。

来自cookie的请求由客户端提供给服务器,服务器将cookie反序列化为数据,解密cookie内容或从数据库检索用户数据。 然后响应出来,服务器序列化客户端数据,刮掉你不会存储在cookie中的东西并将它们放入数据库中,只需在cookie中留下一个id。

如果你正在进行加密,那么当你想通过运行多台机器进行扩展时,这很容易被搞砸,每台机器都需要能够解密数据(不是很难,但是不必要的复杂性)

将未加密的数据放在cookie中并不是最好的,除了cookie中的任何内容之外,还可以为用户添加额外带宽使用量。

2)数据库调用应该非常快,如果不是,那么无论如何你都会在其他地方遇到痛苦的用户体验。 换句话说,我强烈的观点是,对于远离cookie存在压倒性的争论。

考虑每次请求都会发送cookie; 它会更聪明,而不是将数据推入会话并增加开销,在用户发出请求后暂时(缓存)用户数据加载,然后既没有数据库调用也没有来自cookie的开销而用户主动在您的网站上。

老实说,一开始你应该没有缓存。 专注于以最低的复杂性来提升您的应用程序。 这样您就可以根据用户反馈更快地修改它并减少错误。

3)当我玩护照时,我遇到了类似的问题。 我会让护照完成它的工作,并向用户授予护照级别的验证(所以是的,他们已经登录),然后单独进行更多的数据收集。 如果您担心安全问题,请将此护照级别的验证未完全登录,并在升级到完全登录之前需要更多数据。

我可能与这个非常不合适,但这是我的建议。

4)当你有多个节点实例并希望将某些东西存储在内存中时(例如计数器或缓存的用户数据),Redis很适合。 这样,您不会在节点代码中保留有关用户的缓存数据的变量,当用户返回并且负载均衡器将其射向另一个实例时,另一个节点实例无法利用该变量。 http://www.ourdailycodes.com/2013/09/redis-when-should-i-use-it.html

编辑:我应该添加该会话使用cookie,但只给用户一个服务器理解的唯一令牌,以便服务器可以在收到连接并附带会话令牌时重新收集用户的会话数据。 我的理解是,这是Session工作的一般正确方式......但它因实现而异(如果我在这里错了,有人会纠正我)。

我用了node.js这是文档中的代码:

passport.serializeUser(function(user, done) {
   done(null, user.id);
});

passport.deserializeUser(function(id, done) {
   User.findById(id, function (err, user) {
        done(err, user);
   });
});

这是代码,我修改为更好地理解:

var passport = require ('passport')
passport.serializeUser (function(user, done) {
   done(null, user.id);
});

passport.deserializeUser(function(id, done) {
   var user = _.find(fixtures.users, 'id', id)
       if (user) {
          done (null, user);
       }
       else
          { done (null, false) }
});


module.exports = passport;

在serializeUser中,客户端发送带有“id”的cookie。 serializeUser中的'(user)'参数是用户配置文件,客户端仅使用用户配置文件中的'id'向服务器发送请求。 完成回调将user.id传递给服务器。

在deserializedUser中,服务器将查看数据库并从serializedUser中找到具有该“id”的用户并返回用户配置文件。 我使用'lodash'来使用find和remove方法。

var _ = require ('lodash')
var user = _.find(fixtures.users, 'id', id)

find将查找用户ID并返回具有该id的用户配置文件。 关于lodash的更多细节在这里: lodash 之后我检查用户是否存在然后返回用户否则返回false。

最后,我出口护照。

module.exports = passport;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM