限制用户访问其他用户配置文件

时间:2019-05-02 08:40:33

标签: javascript node.js express

我必须通过阻止用户访问其他用户的个人资料来实现我的应用程序的安全性。

route.js

interface KnockoutSubscribableFunctions<T> {
    getMetricValue(divisor): number;
}

和我的 userAuth.js

router.get('/currentUser/:username', userAuth, (req, res) => {
  User.findOne({
    username: req.params.username
  }).then(user => {
    if (user) {
      return res.status(200).json(user);
    } else {
      return res.status(404).json({
        message: 'User not found'
      });
    }
  });
});

现在,如果我以用户 test 的身份登录,那么我的URL将是http://localhost:4200/currentuser/test,但是如果我将URL更改为另一个用户 test2 ,它将重定向并加载test2,即使我已登录为测试

如何防止这种情况?

2 个答案:

答案 0 :(得分:2)

您还需要检查登录用户是否访问了他的数据。

您可以通过针对请求的页面检查令牌中的用户来实现。这意味着您需要在jwt令牌内对用户ID进行编码。这还将确保不干扰此参数,因为如果有人尝试在没有秘密的情况下尝试更改jwt令牌,则jwt.verify将会失败。

您可以在签名时将数据添加到jwt令牌中:

jwt.sign({
  userId: 'username'
}, 'secret', { expiresIn: '1h' });

基本上,如果您保存与serializeUser \ deserializeUser结果相同的数据,它也应该起作用(用户名只是一个建议)。

您可以使用jwt.verify中的回调来获取已解码的令牌并检索该数据

const jwt = require('jsonwebtoken');
module.exports = (req, res, next) => {
  try {
    const token = req.headers.authorization.split(' ')[1];
    jwt.verify(token, 'app_secret_token', (err, decoded) => {
      if (err) { throw err; }

      const currentUsername = decoded.userId; // <-- this should be whatever data you encoded into the jwt token

      // if the user requested is different than the user in the token,
      // throw an authentication failure
      if (req.originalUrl.includes('/currentUser/') &&
          !req.originalUrl.includes(`/currentUser/${currentUsername}`)) {
        throw new Error('access to other user data denied');
       }

       next();
    });

  } catch (error) {
    res.status(401).json({
      message: 'Authentication failed!'
    });
  }
};

即使我认为这可能是将其分成两个不同的中间件的好例子:-)

PS-如@ anand-undavia所述,最好基于jwt令牌本身而不是'url'本身来识别用户请求。这样,每个用户应该只能访问他们自己的数据,而这个问题根本不会发生。

基本上,应该使用上述方法(从令牌中获取用户)或从req.user字段访问用户,如果您使用任何自动添加用户的中间件。

答案 1 :(得分:1)

让我们假设用户个人资料页面ID为mydomian?passedId=userId,那么只需添加profile-guard即可检查谁可以访问或激活此页面,在CanActivate中检查所传递的ID是否与当前用户相同id,然后return true,否则将他重定向到上一页

canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
let passedId: string = next.queryParams.passedId;
  let user = this.authService.GetUser();
  if (user.id == passedId)
    return true;
  else {
    this.router.navigate(['/home']); // or any page like un authorized to log to this page
    return false;
  }
}