首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何处理Express Sessions?

如何处理Express Sessions?
EN

Stack Overflow用户
提问于 2020-01-23 01:25:05
回答 1查看 74关注 0票数 0

我正在尝试处理Node.js、Express、Passport应用程序中的身份验证会话。我编写了几行代码来使用express-session,即使我注册了新用户,它仍然不能进行身份验证。

以下是策略。

代码语言:javascript
复制
// Local Strategy
  passport.use(new LocalStrategy({ usernameField: 'email' }, function(username, password, done){
    User.findOne({ 'email': username }, function(err, user){
      if(err) throw err;
      if(!user){
        return done(null, false, {type: "danger", message: 'No user found'});
      }

      // Match Password
      bcrypt.compare(password, user.password, function(err, isMatch){
        if(err) throw err;
        if(isMatch){
          return done(null, user);
        } else {
          return done(null, false, {type: "danger", message: 'Wrong password'});
        }
      });
    });
  }));

以下是序列化程序。

代码语言:javascript
复制
  passport.serializeUser(function(user, done) {
    console.log(user.id);
    done(null, user.id);
  });

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

这里是登录和注册路由。

代码语言:javascript
复制
// Login page and form
router.get('/login', function(req, res) {
  res.render('login');
});
router.post('/login', passport.authenticate('local',
{successRedirect: '/chat',
failureRedirect: '/login'}));

// Register page and form
router.get('/register', function(req, res) {
  let errors = [];
  res.render('register', { 'errors': '' });
});
router.post('/register', [
  check('name').notEmpty().withMessage('Name field is empty'),
  check('surname').notEmpty().withMessage('Surname field is empty'),
  check('email').notEmpty().withMessage('E-mail is empty'),
  check('password').notEmpty().withMessage('Password field is empty'),
  check('password_confirm').notEmpty().withMessage('Password confirmation field is empty'),
  check("password", "Passwords don't match")
        .custom((value,{req}) => {
            if (value !== req.body.password_confirm) {
                throw new Error("Passwords don't match");
            } else {
                return value;
            }
        }),
], function(req, res) {
  const { name, surname, email, password } = req.body;

  let errors = validationResult(req);

  console.log(errors.errors);

  if(!errors){
    res.render('register', { 'errors': errors.errors });
    console.log('ebebe');
  } else {
    console.log('oooo');
    let NewUser = new User ({
      name, surname, email, password
    });
    bcrypt.genSalt(10, function(err, salt) {
      bcrypt.hash(password, salt, function(err, hash) {
        NewUser.password = hash;
        NewUser.save();
      });
    });
    res.redirect('/chat');
  }
});

这是受保护的路由。

代码语言:javascript
复制
router.get('/chat', (req, res) => {
  if(req.isAuthenticated()) {
      res.send('definitely secure page');
      console.log(req.user);
      console.log(req.isAuthenticated());
  } else {
      res.send('ebebe');
      console.log(req.user);
      console.log(req.isAuthenticated());
  }
});

如何让它正常工作,我做错了什么?

EN

回答 1

Stack Overflow用户

发布于 2020-01-23 03:20:21

这里有一种方法可以做到。您可以结合使用jsonwebtokenexpress-session,并编写一个中间件函数来检查令牌是否有效,并使用它来保护您想要保护的路由。这里有一些代码片段,我希望它们能帮助您朝着正确的方向前进。

首先,您可以在UserSchema中编写一个如下所示的函数,以便稍后在用户登录时使用它生成JWT令牌

代码语言:javascript
复制
var jwt = require('jsonwebtoken');
UserSchema.methods.generateJWT = function() {
    var today = new Date();
    var exp = new Date(today);
    exp.setDate(today.getDate() + 60);

    return jwt.sign({
        id: this._id,
        username: this.username,
        exp: parseInt(exp.getTime() / 1000),
    }, secret);
};

然后,在登录路径中,您可以使用它来生成令牌。

代码语言:javascript
复制
router.post('/login', passport.authenticate('local',
failureRedirect: '/login'}), function(req, res) {
           req.user.token = user.generateJWT();

           req.session.token = req.user.token;
           res.redirect('/dashboard')
});

然后你就可以编写中间件了

代码语言:javascript
复制
function auth(req, res, next) {
  //console.log(req.session.token)
  if (req.session.token) {

    const token = req.session.token


    let decoded = jwt.verify(token, secret)
    console.log(decoded)

    User.findById(decoded.id, function(err, user) {
      if (err || !user) {
        return res.redirect('/')
      }
      //console.log(user)
      res.locals.user = user
      req.user = user
      next()
    })
  } else {
    return res.redirect('/')
  }

}

然后你就可以用它保护你的路线了

代码语言:javascript
复制
router.get('/protected', auth, function(req, res) {


})
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59865149

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档