无需检查跨页面导航的快速JWT令牌访问权限

问题描述

我无法终生弄清楚为什么似乎没有设置或检查我的JWT。

我可以创建一个新用户登录,可以看到bcrypt对密码进行哈希处理并将其保存到数据库中,还可以看到登录/注册后在响应中创建的令牌。

但是,一旦我离开浏览器,即他们应该有权阅读的页面,就会收到错误You need to be logged in to access this route

I asked another question here,因为我一直在努力将最后的难题拼凑在一起,并向我建议说,中间件由于将其安装在'/'路径上而引起了问题,但是按照上面的示例,jwt.verify现在不应该检查令牌吗?

作为一个简单的例子,管理员用户应该能够查看'/ users'路由,但也会遇到相同的错误。我究竟做错了什么?作为参考,我尝试在x-access-token下使用console.log,但是什么都没有输出,所以我真的很困惑。

首先使用以下中间件,并在其下面定义路由器。

app.js

app.use(async (req,res,next) => {
  if (req.headers['x-access-token']) {
    try {
      const accesstoken = req.headers['x-access-token'];
      const {userId,exp} = await jwt.verify(accesstoken,process.env.JWT_SECRET);
      // If token has expired
     console.log('token check');
      if (exp < Date.Now().valueOf() / 1000) {
        return res.status(401).json({
          error: 'JWT token has expired,please login to obtain a new one',});
      }
      res.locals.loggedInUser = await User.findById(userId);
      // console.log('Time:',Date.Now());
      next();
    } catch (error) {
      next(error);
    }
  } else {
    next();
  }
});

app.use('/',userRoutes);

然后在路由器中

router.get('/signup',(req,next) => {
  res.render('signup',{
    viewTitle: 'User SignUp',});
});

router.post('/signup',userController.signup);

router.get('/login',next) => {
  res.render('login',{
    viewTitle: 'User Login',});
});

router.post('/login',userController.login );

router.get('/add',userController.allowIfLoggedin,userController.grantAccess('readAny','profile'),userController.add);

router.get('/users',userController.getUsers);

控制器

// grant access depending on useraccess role
exports.grantAccess = function(action,resource) {
  return async (req,next) => {
    try {
      const permission = roles.can(req.user.role)[action](resource);
      if (!permission.granted) {
        return res.status(401).json({
          error: 'You don\'t have enough permission to perform this action',});
      }
      next();
    } catch (error) {
      next(error);
    }
  };
};

// allow actions if logged in
exports.allowIfLoggedin = async (req,next) => {
  try {
    const user = res.locals.loggedInUser;
    if (!user) {
      return res.status(401).json({
        error: 'You need to be logged in to access this route',});
    }
    req.user = user;
    next();
  } catch (error) {
    next(error);
  }
};

// sign up
exports.signup = async (req,next) => {
  try {
    const {role,email,password} = req.body;
    const hashedPassword = await hashPassword(password);
    const newUser = new User({email,password: hashedPassword,role: role || 'basic'});
    const accesstoken = jwt.sign({userId: newUser._id},process.env.JWT_SECRET,{
      expiresIn: '1d',});
    newUser.accesstoken = accesstoken;
    await newUser.save();
    res.send({
      data: newUser,message: 'You have signed up successfully',});
  } catch (error) {
    next(error);
  }
};

exports.login = async (req,next) => {
  try {
    const {email,password} = req.body;
    const user = await User.findOne({email});
    if (!user) return next(new Error('Email does not exist'));
    const validPassword = await validatePassword(password,user.password);
    if (!validPassword) return next(new Error('Password is not correct'));
    const accesstoken = jwt.sign({userId: user._id},});
    await User.findByIdAndUpdate(user._id,{accesstoken});
    res.status(200).json({
      data: {email: user.email,role: user.role},accesstoken,});
  } catch (error) {
    next(error);
  }
};

// get all users
exports.getUsers = async (req,next) => {
  const users = await User.find({});
  res.status(200).json({
    data: users,});
};

任何建议将不胜感激!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)