NodeJS + Express: паспорт против OAuth2 в зависимости от области действия (права доступа) - PullRequest
0 голосов
/ 07 сентября 2018

Представьте, что я внедряю службу API на api .example.com, которая должна защищать свои конечные точки с помощью OAuth2 с достаточной степенью детализации для размещения пользователей разных типов.

  • пользователи, которые проходят аутентификацию на Facebook, могут получить доступ только к https://api.example.com/facebook
  • пользователи, которые проходят аутентификацию на Twitter, могут получить доступ только к https://api.example.com/twitter
  • пользователи, которые аутентифицируются локально с помощью службы авторизации, могут получить доступ к конечным точкам Facebook и Twitter

Это означает, что у нас есть следующие роли:

  • Провайдер аутентификации (Сервер авторизации, Facebook, Twitter)
  • Поставщик авторизации (сервер My OAuth2) ( auth .example.com)
  • Поставщик ресурсов (Мой API-сервер) ( api .example.com)
  • Веб-приложение ExpressJS или SPA ( www .example.com) или собственное приложение

Вопросы:

Q1 Как реализовать поток приложений?

Мои мысли ...

Веб-приложение должно сохранить accessToken для api .example.com в сеансе и отправить идентификатор сеанса в веб-браузер. Если accessToken отсутствует, он должен перенаправить браузер на auth .example.com / login / selectprovider /, указав client_id = " www .example.com" и client_secret, и REDIRECT_URL = "https://www.example.com/".

В https://auth.example.com/login/selectprovider/ пользователь выбирает Facebook или Twitter или локальный, а auth .example.com перенаправляет пользователя (снова) на / login или Facebook или Twitter, используя client_id и client_secret и redirect_url = https://auth.example.com/twitter или https://auth.example.com/twitter, чтобы легко различать три.

Методы Facebook / twitter / local аутентифицируют пользователя и перенаправляют браузер обратно на auth .example.com.

auth .example.com затем сгенерирует (Bearer) accessToken для api .example.com и сохранит его вместе с user.id в таблице локальной базы данных, с связанную область («facebook», «twitter» или «local»), введите ключ (userId) в сеанс браузера и перенаправьте на https://www.example.com/

Теперь, когда пользователь нажимает на ссылку в WebApp, www .example.com выполняет GET или POST на api .example.com, предоставляя client_id = "www. example.com "client_secret и access_token.

Конечные точки api .example.com проверяют accessToken и, если все в порядке, выполняют API и возвращают значение www .example.com, которое отображает его в браузере пользователь.

Q2 Выше правильного расхода или есть лучший способ? Если правильно, как api .example.com проверяет accessToken на его конечных точках?

Если auth .example.com предоставляет для этого специальную конечную точку (например, / userinfo), к которой можно получить доступ только с помощью client_id = " api .example.com" и client_secret? Это кажется дорогостоящим для каждого вызова, но как еще api .example.com может доверять действию токена (потому что он истек или пользователь вышел из системы)?

Что такое стандарт OAuth2?

Q3 В примерах passport / OAuth2orize я вижу 3 способа проверки подлинности:

  • if (req.user) {...};
  • if (req.isAuthenticated ()) {...};
  • passport.authenticate ('bearer', {session: false);

Q4 Что именно делает passport.authenticate ('facebook')?

Эта информация представлена ​​в стратегии.

passport.use(new FacebookStrategy({
    clientID: FACEBOOK_APP_ID,
    clientSecret: FACEBOOK_APP_SECRET,
    callbackURL: "http://localhost:3000/auth/facebook/callback"
  },
  function(accessToken, refreshToken, profile, cb) {
    User.findOrCreate({ facebookId: profile.id }, function (err, user) {
        return cb(err, user);
    });
  }
));

Так что это содержит client_id и client_secret. Когда это используется? Каждый раз, когда вызывается passport.authenticate ('facebook')? Делает ли вся переадресация на страницу входа в Facebook, получает ли код авторизации и обменивает ли его на accessToken, каким-то образом хранит accessToken и сохраняет его до выхода из системы?

Это кажется маловероятным, но я не понимаю, как он может на самом деле аутентифицировать пользователя без всего этого. И это было бы слишком дорого для каждого вызова API, поэтому я уверен, что он работает более эффективно. Но я не знаю, как и изучение исходного кода не сделало его более ясным.

Q5 Как * api **. Example.com узнает, когда доступный токен на предъявителя, включенный www .example.com в каждый запрос API, не подделан или не истек?

Я полагаю, что он должен проверить это по отношению к службе auth .example.com, и эта служба, в свою очередь, должна проверить, является ли сеанс facebook / twitter по-прежнему действительным, и обновить токены, используя refreshToken по адресу в тот момент?

...