nodejs重定向后更改会话变量

发布于 2025-01-31 03:02:21 字数 2083 浏览 2 评论 0原文

我有一个登录系统,用户将数据发布到 /登录路由,如果正确登录,它将保存数据。

router.post('/login', function(req, res, next) {
  if(req.method == 'POST') {
    const username = req.body.username;
    const password = req.body.password;
    sql.query('SELECT * FROM `users` WHERE `username` = "'+username+'"', function(err, results) {
      if(err) { 
        req.session.message = {status: 'danger', message: 'Failed to login, check password.'}
        res.redirect('/')
      } else if (results.length != 0) {
        const passw = results[0].password;
        bcrypt.compare(password, passw, function(err, result) {
          if(result) {
            req.session.loggedin = true;
            req.session.data = results[0];
            req.session.message = {status: 'success', message: `Welcome back, ${username}.`}
            req.session.save(function(err) {
                res.redirect(req.headers.referer);
            })
          } else {
            req.session.message = {status: 'danger', message: 'Failed to login, check password.'}
            res.redirect('/')
          }
        });
      } else {
        req.session.message = {status: 'danger', message: 'Failed to login, check username.'}
        res.redirect('/')
      }
    })
  }
});

因此,它将数据保存并重定向到索引消息显示一次。

我尝试了:

delete req.session.message

但这只是在变量传递给下一个请求之前删除该变量。

我如何显示消息:

<script type="text/javascript">
   var message = JSON.parse('<%- JSON.stringify(message) %>');
   $(document).ready(function(){
      if(message != null) {
         $('.toast').addClass('bg-' + message.status);
         $('.toast-body').html(message.message)
         $(".toast").toast('show');
      }
   });        
</script>

如何呈现数据:

if(req.session.loggedin) {
    res.render('index', {
        loggedin: true,
        data: req.session.data,
        message: req.session.message
    });
} else {
    res.render('index', {
        loggedin: false,
        data: null,
        message: req.session.message
  });
}

I have a login system, user posts data to /login route and it saves data if logged correctly.

router.post('/login', function(req, res, next) {
  if(req.method == 'POST') {
    const username = req.body.username;
    const password = req.body.password;
    sql.query('SELECT * FROM `users` WHERE `username` = "'+username+'"', function(err, results) {
      if(err) { 
        req.session.message = {status: 'danger', message: 'Failed to login, check password.'}
        res.redirect('/')
      } else if (results.length != 0) {
        const passw = results[0].password;
        bcrypt.compare(password, passw, function(err, result) {
          if(result) {
            req.session.loggedin = true;
            req.session.data = results[0];
            req.session.message = {status: 'success', message: `Welcome back, ${username}.`}
            req.session.save(function(err) {
                res.redirect(req.headers.referer);
            })
          } else {
            req.session.message = {status: 'danger', message: 'Failed to login, check password.'}
            res.redirect('/')
          }
        });
      } else {
        req.session.message = {status: 'danger', message: 'Failed to login, check username.'}
        res.redirect('/')
      }
    })
  }
});

so it saves the data and redirects to index but everytime a user goes on the index page it shows the Welcome message, it obviously does this because the variable is still defined so my goal is to change that variable too null after they login and the welcome message shows up once.

ive tried:

delete req.session.message

but this just deletes the variable before it gets passed to the next request.

How im displaying the message:

<script type="text/javascript">
   var message = JSON.parse('<%- JSON.stringify(message) %>');
   $(document).ready(function(){
      if(message != null) {
         $('.toast').addClass('bg-' + message.status);
         $('.toast-body').html(message.message)
         $(".toast").toast('show');
      }
   });        
</script>

How im rendering the data:

if(req.session.loggedin) {
    res.render('index', {
        loggedin: true,
        data: req.session.data,
        message: req.session.message
    });
} else {
    res.render('index', {
        loggedin: false,
        data: null,
        message: req.session.message
  });
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

静若繁花 2025-02-07 03:02:21

渲染包含消息的页面后,您需要从会话中清除消息:

if (req.session.loggedin) {
    res.render('index', {
        loggedin: true,
        data: req.session.data,
        message: req.session.message
    });
} else {
    res.render('index', {
        loggedin: false,
        data: null,
        message: req.session.message
    });
}
req.session.message = null;
req.session.save();

为了避免在重定向和保存会话之间发生任何竞赛条件的机会,在手动保存会话之前,您不应重定向。问题是,在您发送res.redirect()之后,依靠Express-Session的会话自动保存将尝试保存会话,但发送res.redirect( )告诉浏览器立即请求另一个页面,以便您在会话的自动保存和新的传入请求之间设置竞赛,从res.redirect()。你不想要那场比赛。您想在发布重定向之前确保会话已保存。因此,我将res.redirect()放入req.session.save()回调中,以避免任何可能的比赛条件:

router.post('/login', function(req, res, next) {
  if(req.method == 'POST') {
    const username = req.body.username;
    const password = req.body.password;
    sql.query('SELECT * FROM `users` WHERE `username` = "'+username+'"', function(err, results) {
      if(err) { 
        req.session.message = {status: 'danger', message: 'Failed to login, check password.'}
        res.redirect('/')
      } else if (results.length != 0) {
        const passw = results[0].password;
        bcrypt.compare(password, passw, function(err, result) {
          if(result) {
            req.session.loggedin = true;
            req.session.data = results[0];
            req.session.message = {status: 'success', message: `Welcome back, ${username}.`}
            req.session.save(function(err) {
                res.redirect(req.headers.referer);
            })
          } else {
            req.session.message = {status: 'danger', message: 'Failed to login, check password.'}
            req.session.save(() => {
                res.redirect('/')
            });
          }
        });
      } else {
        req.session.message = {status: 'danger', message: 'Failed to login, check username.'}
        req.session.save(() => {
            res.redirect('/')
        });
      }
    })
  }
});

After you render your page containing the message, you need to clear the message from the session:

if (req.session.loggedin) {
    res.render('index', {
        loggedin: true,
        data: req.session.data,
        message: req.session.message
    });
} else {
    res.render('index', {
        loggedin: false,
        data: null,
        message: req.session.message
    });
}
req.session.message = null;
req.session.save();

And, to avoid any chance of a race condition between a redirect and saving the session, you should not redirect until you've manually saved the session. The issue is that relying on the auto-save of the session by express-session will attempt to save the session AFTER you send the res.redirect(), but sending the res.redirect() tells the browser to immediately request another page so you set up a race between the auto-save of the session and the new incoming request from res.redirect(). You don't want that race. You want to make sure the session has been saved before you issue the redirect. So, I put the res.redirect() inside a req.session.save() callback to avoid any possible race condition:

router.post('/login', function(req, res, next) {
  if(req.method == 'POST') {
    const username = req.body.username;
    const password = req.body.password;
    sql.query('SELECT * FROM `users` WHERE `username` = "'+username+'"', function(err, results) {
      if(err) { 
        req.session.message = {status: 'danger', message: 'Failed to login, check password.'}
        res.redirect('/')
      } else if (results.length != 0) {
        const passw = results[0].password;
        bcrypt.compare(password, passw, function(err, result) {
          if(result) {
            req.session.loggedin = true;
            req.session.data = results[0];
            req.session.message = {status: 'success', message: `Welcome back, ${username}.`}
            req.session.save(function(err) {
                res.redirect(req.headers.referer);
            })
          } else {
            req.session.message = {status: 'danger', message: 'Failed to login, check password.'}
            req.session.save(() => {
                res.redirect('/')
            });
          }
        });
      } else {
        req.session.message = {status: 'danger', message: 'Failed to login, check username.'}
        req.session.save(() => {
            res.redirect('/')
        });
      }
    })
  }
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文