Паспорт: разрешить доступ к маршруту на основе данных пользователя - PullRequest
0 голосов
/ 01 июля 2019

В настоящее время я использую экспресс в качестве бэкэнда для своего приложения реакции. Чтобы защитить некоторые маршруты, я использую паспорт JWT, чтобы гарантировать, что пользователи вошли в систему и имеют действительный токен для доступа к различным частям приложения.

У меня может быть несколько маршрутов, доступ к которым могут получить все пользователи, а доступ к ним могут иметь только определенные пользователи. Например:

/api/online доступно для всех, кто вошел в систему.

/api/users/ должны быть доступны только пользователям с особыми разрешениями.

Эти разрешения предварительно установлены в документе MongoDB пользователя в виде массива.

Когда пользователи входят в систему, к их токену прикрепляется следующая полезная нагрузка:

 const payload = {
          id: user.id,
          name: user.name,
          permissions: user.permissions
        };

Идентификатор соответствует их идентификатору документа MongoDB, а разрешения извлекаются непосредственно из их документа и сохраняются в их токене полезной нагрузки. Они точно определяют, к каким маршрутам имеет доступ пользователь.

Затем я настраиваю паспорт следующим образом:

passport.use(
    new JwtStrategy(opts, (jwt_payload, done) => {
      if (!userCache[jwt_payload.id])
        User.findById(jwt_payload.id)
          .then(user => {
            if (user) {
              userCache[jwt_payload.id] = user;
              setTimeout(() => {
                delete userCache[jwt_payload.id]
              }, 60 * 60 * 1000);//make sure data is up to date by the hour
              return done(null, user);
            }
            return done(null, false);
          })
          .catch(err => {
            console.log(err)
          });
      else done(null, userCache[jwt_payload.id]);
    })
  );

Не беспокойтесь о моей системе кеширования, я планирую улучшить ее, чтобы она автоматически обновлялась при изменении модели Users. Моя проблема в том, что в этом методе позволяет реализовать паспорт, нет способа проверить фактический маршрут, к которому осуществляется доступ. jwt_payload содержит массив полномочий, который я установил ранее, но он бесполезен, так как я не могу проверить маршрут, чтобы убедиться, что пользователь авторизован. Вот как я сейчас авторизую маршруты:

app.get('/api/online', passport.authenticate('jwt', {session: false}), (req, res) => {//fetch the current amount of people online
    res.setHeader('Content-Type', 'text/plain');
    res.send(userServer.connectionCount.toString());

  });

Это прекрасно работает, так как этот маршрут должен быть доступен всем, кто вошел в систему, однако, что если я хочу использовать маршрут /api/users? Я не знаю, как передать специальную строку, чтобы сказать «этот маршрут должен быть разрешен только пользователям с разрешением x.

Есть предложения?

Я пробовал

  • api.use('/api/users',(req,res,next)=>{}) но поиск способа расшифровки токена аутентификации без паспорта звучит немного лишним и добавляет сложности, которую должен решить паспорт. Кроме того, заставить клиента вручную передавать свои разрешения для решения предыдущей проблемы - это огромный риск для безопасности, поскольку любой может просто создать свои разрешения и прикрепить его к телу запроса.
  • Несколько паспортов с разными конфигами. Затем, позволяя мне переходить к различным маршрутам passport.authenticate. Казалось невозможным, или я делал что-то не так.

Спасибо.

...