【问题标题】:Issue with client-session middleware: req.session_state = undefined after being set客户端会话中间件问题:设置后 req.session_state = undefined
【发布时间】:2016-02-22 14:04:00
【问题描述】:

让客户端会话中间件在 Express 中工作时遇到了一些问题。简而言之,在设置后重定向到新路由时似乎无法访问 session_state。作为参考,我关注了this video tutorial(客户端会话部分大约在 36:00 开始)并仔细检查了我的步骤,但仍然遇到问题。中间件设置如下:

var sessions = require('client-sessions');

使用来自 Express 网站的代码进行实例化。

app.use(sessions({
 cookieName: 'session',
 secret: 'iljkhhjfebxjmvjnnshxhgoidhsja', 
 duration: 24 * 60 * 60 * 1000,
 activeDuration: 1000 * 60 * 5 
}));

如果有任何区别,我将会话中间件放置在 bodyParser 和路由之间。

以下是我的routes/index.js 与该问题相关的部分。 req.session_state 似乎设置正常,并且正确的用户详细信息记录到控制台。

// POST login form
router.post('/login', function(req, res) {
  User.findOne( { email: req.body.email }, function(err,user){
    if(!user) {
      console.log("User not found...");
      res.render('login.jade', 
         { message: 'Are you sure that is the correct email?'} );
    } else {
        if(req.body.password === user.password) {

        // User gets saved and object logs correctly in the console
            req.session_state = user;
            console.log("session user...", req.session_state);

            res.redirect('/dashboard'); 
        }
    }
    //res.render('login.jade', { message: 'Invalid password'} );
  });
});

但是,运行 res.redirect('/dashboard'); 时出现了问题,因为 session_state 在到达该路由时不可访问。这是/dashboard 路由的代码。

router.get('/dashboard', function(req, res) {

   // OUTPUT = 'undefined' ???
   console.log("dash...", req.session_state);

   // 'if' fails and falls through to /login redirect
   if(req.session && req.session_state){
       console.log("dash route...", req.session_state);
       User.findOne( { email: req.session_state.email }, function
        (err, user){
         if(!user){
            req.session.reset();
            res.redirect('/login');
         } else {
            res.locals.user = user;
            res.render('dashboard.jade')
         }
      });
   } else {
    res.redirect('/login');
   }
   //res.render('dashboard', { title: 'Your Dashboard' });
});

基本上,存储在 session_state 中的对象在 /dashboard 重定向后无法访问。我一直在尝试调试它一天左右,但没有任何运气。非常感谢任何帮助。抱歉,如果我遗漏了一些明显的东西。只是用会话中间件弄湿了我的脚,所以也许我还没有完全掌握 Session 或者我忽略了一些东西。提前致谢!

【问题讨论】:

    标签: javascript node.js session express session-cookies


    【解决方案1】:

    我已经用可以帮助您设置 cookie 和称为令牌的替代会话管理器的代码更新了我的答案。在此示例中,我已将部件提供给中间件,其中一部分附加 cookie(可以扩展以确定您的用例),第二部分检查令牌是否过期或其中可能存在的其他内容(即受众、发行人等)

     app.use('/js/',function(req, res, next) {
    //check if the request has a token or if the request has an associated username
             if(!req.headers.cookie){
    
                console.log('no cookies were found')
    
                var token = jwt.sign({user_token_name:req.body.user_name},app.get('superSecret'), {
                    expiresIn: 1 *100 *60 // expires in 1 mintue can be what ever you feel is neccessary
                });
                 //make a token and attach it to the body
                 // req.body.token = token // this is just placing the token as a payload
                 res.cookie('austin.nodeschool' , token,{ maxAge: 100000, httpOnly: true }) //this sets the cookie to the string austin.nodeschool
             }
            if(req.body.user_name){
                 next()
             }else{
                 res.send('request did not have a username').end() // this is here because my middleware also requires a username to be associated with requests to my API, this could easily be an ID or token.
             }
        },function(req, res, next) {
    //    console.log(req.headers)  this is here to show you the avilable headers to parse through and to have a visual of whats being passed to this function
                if(req.headers.cookie){
                    console.log(req.headers.cookie) //the cookie has the name of the cookie equal to the cookie.
                    var equals = '=';
                    var inboundCookie = req.headers.cookie
                    var cookieInfo = splitCookie(inboundCookie,equals) //splitCookie is a function that takes the inbound cookie and splits it from the name of the cookie and returns an array as seen below.
                    console.log(cookieInfo)
                   var decoded = jwt.verify(cookieInfo[1], app.get('superSecret'));
    
                    console.log(decoded)
                    // You could check to see if there is an access_token in the database if there is one
                    // see if the decoded content still matches. If anything is missing issue a new token
                    // set the token in the database for later assuming you want to       
                    // You could simply check if it's expired and if so send them to the login if not allow them to proceed through the route. 
                }
        next()
        });
    

    【讨论】:

    • 感谢您的回复,但我不确定我是否关注您。如果我理解正确,重定向会导致会话中的所有用户数据被删除?这似乎破坏了目的会话中间件。此外,如果您在 42:20 左右检查 tutorial video,他在到达 /dashboard 路由后清楚地检索了会话 cookie 数据。如果我遗漏了一些东西,再次道歉,但我仍然很困惑为什么我的代码会为session_state 抛出undefined,尽管据我所知,tut 中的代码基本相同。
    • @mikeym 当您在请求中点击路由时,您是否会在浏览器开发者控制台的资源下看到会话存储?
    • 资源中没有显示任何内容 > 会话存储。但这就是我所期望的,因为/dashboard GET 正在为节点控制台日志中的 session_state 返回undefined。我该如何解决这个问题并让 session_state 在/dashboard 路由中可访问?感谢您的帮助。
    • 你的前端在做什么?您正在将会话附加到请求并使用重定向进行响应。您没有将会话附加到响应中,因此前端没有获取会话令牌来存储在浏览器中。您需要关联的客户端代码来处理会话响应并将会话令牌存储在浏览器中// Save data to sessionStoragesessionStorage.setItem('key', 'value');// Get saved data from sessionStoragevar data = sessionStorage.getItem('key');
    • @mikeym 我发现这条线搞砸了。 // sets a cookie with the user's info req.session.user = user; 您在登录时使用 res.session_state = user。
    猜你喜欢
    • 2022-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    • 2020-01-19
    • 2017-05-31
    • 2011-06-14
    相关资源
    最近更新 更多