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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (176)

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

RedisStore被设置为我的使用Express的会话存储。这是否意味着我没有实现序列化和反序列化?会自动发生吗?

当我不实现这些方法时,我会得到以下Express错误-500错误:未能将用户序列化为会话。当我实现它们时,我不知道在反序列化中放什么。

有没有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 );
});
提问于
用户回答回答于

何时和如何调用策略/local/facebook/etc,以及如何获得req.login或passport.erializeUser(),以及do()是什么?

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

已完成的回调返回到passport.authenticate()。如果已完成,则在前面与用户一起调用(如done(null,user);req,logIn()自动调用或由幕后用户调用。

req.logIn()打电话passport.serializeUser()

  1. 什么是passport.erializeUser,以及user.ome在哪里?_在这个函数被调用之后,键去?

在序列化函数的第二个参数中提供的用户对象的键保存在会话中,并通过反序列化函数来检索整个对象。

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

  1. Passport.deserializeUser是什么,它在工作流中的位置是什么?

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

将获取的对象附加到请求对象,如req.user

id键可以是用户对象的任意键name,email

视觉流

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

用户回答回答于

将Redis实现为会话存储与护照的实现无关,它只处理存储会话数据的位置。

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()提供了一个接受两个参数的函数,即用户配置文件(user)和回调函数(done那就是。回调函数的第二个参数是标识信息(user.id,但是如果您使用MongoDB,这可能是user._id)需要从数据库中恢复帐户。这将在每个经过身份验证的请求上调用,并将标识信息存储在会话数据中。

passport.deserializeUser()提供了一个函数,该函数还接受两个参数,即标识信息(id)和回调函数(done那就是。标识信息是在上一次请求中序列化到会话数据的信息(user.id那就是。这里的回调函数要求用户配置文件作为其第二个参数,或者在检索概要文件时出现的任何错误,作为它的第一个参数。大User.findById()函数是数据库中用户配置文件的查找函数。在这个例子中User对象是一个猫鼬模型的实例,该模型具有findByid()功能。

提供给passport.deserializeUser()被护照中间件调用,passport.session()在存储用户配置文件的路由处理之前(user()req.user

将Redis实现为会话存储

使用Redis的目的是存储会话数据服务器端,因此存储的客户端数据只有会话ID。同样,如何实现护照无关,只要在应用程序中添加了会话支持,护照就不关心会话数据存储在哪里。

扫码关注云+社区

领取腾讯云代金券