запретить пользователям доступ к другим профилям пользователей - PullRequest
0 голосов
/ 02 мая 2019

Мне необходимо внедрить защиту в моем приложении, запретив пользователям доступ к профилю других пользователей.

route.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'
      });
    }
  });
});

и мой userAuth.js

const jwt = require('jsonwebtoken');
module.exports = (req, res, next) => {
  try {
    const token = req.headers.authorization.split(' ')[1];
    jwt.verify(token, 'app_secret_token');
    next();
  } catch (error) {
    res.status(401).json({
      message: 'Authentication failed!'
    });
  }
};

Теперь, если я вошел в систему как пользователь test , поэтому мой URL будет http://localhost:4200/currentuser/test, но если я изменю свой URL на другого пользователя test2 , он перенаправит и загрузит test2, хотя я вошел как test

как мне это предотвратить?

Ответы [ 2 ]

2 голосов
/ 02 мая 2019

Вам также необходимо убедиться, что вошедший в систему пользователь получает доступ к своим данным.

Вы можете достичь этого, сверяя пользователя в токене с запрошенной страницей. Это означает, что вам нужно закодировать идентификатор пользователя внутри токена jwt. Это также гарантирует, что этот параметр не был добавлен, поскольку jwt.verify не будет работать, если кто-то попытается изменить токен jwt без секрета.

вы можете добавить эти данные в токен 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 голос
/ 02 мая 2019

давайте предположим, что идентификатор страницы профиля пользователя mydomian?passedId=userId, поэтому просто добавьте profile-guard, чтобы проверить, кто может посещать или активировать эту страницу, в CanActivate проверьте, что переданный идентификатор совпадает с идентификатором текущего пользователя, затем 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;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...