简体   繁体   English

客户端会话中间件的问题:设置后req.session_state = undefined

[英]Issue with client-session middleware: req.session_state = undefined after being set

I've hit a bit of a problem getting client-session middleware working in Express. 在Express中使用客户端会话中间件时,我遇到了一些问题。 In short the session_state doesn't seem to be accessible when redirecting to new route after being set. 简而言之,在设置后重定向到新路由时,似乎无法访问session_state。 For reference I have followed this video tutorial (client-session part starts 36:00 approx.) and double checked my steps but still encountering problems. 作为参考,我已经按照此视频教程进行操作 (客户端会话部分开始于36:00左右),并仔细检查了我的步骤,但仍然遇到问题。 Middleware is set up as follows: 中间件设置如下:

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

Instantiated with code from the Express website. 从Express网站上的代码实例化。

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

I have the sessions middleware placed between bodyParser and routes if that makes any difference. 我将会话中间件放在bodyParser和路由之间,如果有区别的话。

Here are the sections my routes/index.js pertaining to the issue. 这是我的routes/index.js与该问题有关的部分。 The req.session_state seems to get set ok and the correct user details log to the console. 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'} );
  });
});

However, something is going wrong when the res.redirect('/dashboard'); 但是,当res.redirect('/dashboard');出问题了res.redirect('/dashboard'); is run because the session_state is not accessible when it hits that route. 之所以运行,是因为session_state到达该路由时不可访问。 Here is the code for the /dashboard route. 这是/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' });
});

Basically, the object stored in session_state is not accessible after the /dashboard redirect. 基本上,存储在session_state中的对象在/dashboard重定向后不可访问。 I've been trying to debug it for a day or so without any luck. 我一直在调试它大约一天,没有运气。 Any help much appreciated. 任何帮助,不胜感激。 Sorry if I am missing something obvious. 抱歉,如果我缺少明显的内容。 Just getting my feet wet with session middleware so maybe I haven't fully grasped Session or I am overlooking something. 只是用会话中间件弄湿了,所以也许我还没有完全掌握Session或我正在忽略某些东西。 Thanks in advance! 提前致谢!

I've updated my answer with code that should help you set the cookie and an alternative session manager known as a token. 我已经用代码更新了我的答案,该代码应该可以帮助您设置Cookie和一个称为令牌的替代会话管理器。 In this example I've provided to parts to a middle ware one part which attaches the cookie (this can be expanded on to determine your use case) and the second part which checks the token for expiration or what ever else might be in there (ie audience, issuer, etc.) 在本示例中,我为中间件提供了一部分,其中一部分附加了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()
    });

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

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