我是否实现序列化和反序列化NodesJS + Passport + RedisStore?

我是否实现序列化和反序列化?

RedisStore被设置为我的会话存储与Express。 这是否意味着我不执行序列化和反序列化? 会自动发生吗?

当我不执行这些方法时,我得到以下快速错误 – 500错误:无法序列化用户进入会话。 当我执行它们时,我不确定要在反序列化中放置什么。

下面的代码似乎工作,但会议不坚持。 我每次访问该网站时都需要login。

在NodeJS + Passport + RedisStore的任何地方都有一个很好的例子吗?

var sessionStore = new RedisStore({ host: rtg.hostname, port: rtg.port, db: redisAuth[0], pass: redisAuth[1] }); passport.use(new ForceDotComStrategy({ clientID: clientId, clientSecret: clientSecret, callbackURL: myurl }, function(token, tokenSecret, profile, done) { console.log(profile); return done(null, profile); } )); appSecure.configure('production', function(){ appSecure.use(allowCrossDomain); appSecure.use(express.cookieParser(expressSecret)); appSecure.use(express.bodyParser()); appSecure.use(express.methodOverride()); appSecure.set('port', port); appSecure.use(express.session({ secret: expressSecret, store: sessionStore, key:'expressSid', cookie: { maxAge : 604800, domain:'.domain.com'}})); appSecure.use(passport.initialize()); appSecure.use(passport.session()); appSecure.use(appSecure.router); appSecure.use(express.static(__dirname + '/public')); appSecure.use(express.errorHandler()); }); passport.serializeUser(function( user, done ) { done( null, user.id); }); passport.deserializeUser(function( user, done ) { done( null, user ); }); 

如果您使用会话,您必须提供序列化和反序列化function的护照。 实现Redis作为会话存储与如何实现Passport无关,它仅处理会话数据的存储位置。

用护照实施会议

正如我所说的,序列化和反序列化function必须提供给会议才能工作的护照。

序列化函数的目的是返回足够的标识信息以在任何后续请求上恢复用户帐户。 具体来说, done()方法的第二个参数是序列化到会话数据中的信息

您提供的反序列化函数旨在基于序列化到会话的标识信息返回用户configuration文件

以下是讨论会话部分中护照指南的示例:

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

在上面的例子中, passport.serializeUser()提供了一个函数,它带有两个参数:用户configuration文件( user )和callback函数( done )。 callback函数将第二个参数作为从数据库中恢复帐户所需的标识信息( user.id ,但是如果您使用的是mongoDB,这可能是user._id )。 这将在每个经过validation的请求上调用,并将标识信息存储在会话数据中(无论是在Cookie还是在您的Redis存储中)。

passport.deserializeUser()提供了一个函数,该函数还需要两个参数,即标识信息( id )和一个callback函数( done )。 标识信息是序列化到前一个请求( user.id )中的会话数据的信息。 这里的callback函数需要用户configuration文件,因为它是第二个参数,或者在检索configuration文件时引发的任何错误,因为它是第一个参数。 User.findById()函数是数据库中用户configuration文件的查找函数。 在这个例子中, User对象是具有findById()函数的mongoose模型的一个实例。

提供给passport.deserializeUser()的函数在路由处理之前由护照中间件passport.deserializeUser()调用以将用户简档( user )存储到req.user

实施Redis作为会话存储

使用Redis的目的是存储会话数据服务器端,所以存储在客户端的唯一数据就是会话ID。 同样,这与您如何实施护照无关,只要您已将会话支持添加到您的应用程序,护照不关心会话数据的存储位置。 这个关于stackoverflow的previos问题解决了如何实现Redis

有点晚了,但我已经使这个视觉的东西了解

  1. 什么时候以及如何是一个策略/本地/ Facebook /等调用,以及如何得到req.login或passport.serializeUser()和whats done()?

passport.authenticate()调用您提供的相应策略作为参数,在那里您将req.body.passwordreq.body.username与存储的数据库或内存中存储的密码和用户名相匹配。 如果用户发现你把它传递给done()作为第二个参数,否则return false

完成的callback返回到passport.authenticate() 。 如果完成之前被用户调用(即done(null,user); )比req,logIn()被自动调用或由用户在场景后面调用

req.logIn()调用passport.serializeUser()

  1. Whats passport.serializeUser和user.some_key在这个函数被调用后去哪里?

在serialize函数中done中的第二个参数中提供的用户对象的关键字保存在session中,用于通过反序列化函数检索整个对象。

序列化函数确定用户对象中的哪些数据应该存储在会话中。 serializeUser方法的结果作为req.session.passport.user = {}连接到会话,例如它会(因为我们提供id作为键) req.session.passport.user = {id:'xyz'}

  1. 什么是passport.deserializeUser,它在哪里适合工作stream?

在deserialize函数的第一个参数中提供的反序列化函数中,在serialize调用中赋予完成函数的用户对象的同一个键。 所以你的整个对象是借助该键来检索的。 在这里键是id(键可以是用户对象的任何键,例如名称,电子邮件等)在密钥与存储器数组/数据库或任何数据资源中匹配的deSerialize函数中

获取的对象作为req.user附加到请求对象

id键可以是用户对象的任何键,例如name,email

可视化stream程

 passport.authenticate()----------- | | invokes \./ passport.use(new LocalStrategy( function(username, password, done) { // match req.body.username and req.body.password from any //data base or in memory array if(user_is_found_and_pass_match) done(null,user);-- else | *1-user passed | done(null,false);---| *2-user not passed }); | |return back to passport.authenticate() <------------ | | |----- if user is passed in done() (*1) , | req.login() <--------- | //authenticate() middleware may invoke req.login() automatically. | | calls \./ passport.serializeUser(function(user, done) { done(null, user.id); | //use 'id'to serialize, you can use other or user object itself }); |-->saved to session req.session.passport.user = {id:'..'} | |__________________ | passport.deserializeUser(function(id, done) { ________________| | User.findById(id, function(err, user) { done(err, user); |______________>user object ataches to the request as req.user }); }); 

这里的id键可以是用户对象的任何键,例如name,email

给出以下会话存储与connect-redisexpress-sessionconfiguration(使用Express 4):

 redis = require('redis').createClient(6379, '127.0.0.1'); session = require('express-session'); RedisStore = require('connect-redis')(session); app.use(session({ store: new RedisStore({ client: redis }), secret: 's3cret', resave: true, saveUninitialized: true })); 

你可以告诉护照序列化整个用户对象,而不仅仅是用户ID。

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

整个用户对象将在会话中保存在Redis中,并作为req.user放在请求上。