Статьи

Социальная аутентификация для приложений Node.js с паспортом

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

Простой обходной путь — позволить пользователям проходить аутентификацию через свои существующие социальные учетные записи, такие как Facebook, Twitter, Google и т. Д. В этой статье мы собираемся сделать это и добавить эту возможность входа в социальную сеть в пример приложения Node, разработанного в первой части эта серия аутентификации, чтобы мы могли проходить аутентификацию через наши учетные записи Facebook и Twitter с использованием промежуточного программного обеспечения Passport .

Если вы еще не ознакомились с предыдущей статьей , я бы порекомендовал вам пройти ее, поскольку мы будем опираться на фундамент, заложенный в этой статье, и добавим в нее новые стратегии, маршруты и представления.

Для непосвященных, социальный вход — это тип единого входа, использующий существующую информацию с сайтов социальных сетей, таких как Facebook, Twitter и т. Д., Где обычно ожидается, что у пользователей уже есть учетные записи.

Социальный вход в систему в основном основан на схеме аутентификации, такой как OAuth 2.0 . Чтобы узнать больше о различных потоках входа в систему, поддерживаемых OAuth, прочитайте эту статью . Мы выбираем Passport для управления социальным входом для нас, поскольку он предоставляет различные модули для различных поставщиков OAuth, будь то Facebook, Twitter, Google, GitHub и т. Д. В этой статье мы будем использовать модули passport-facebook и passport-twitter обеспечить функциональность входа через существующие учетные записи Facebook или Twitter.

Чтобы включить аутентификацию Facebook, сначала нужно создать приложение Facebook с помощью портала разработчиков Facebook . Запишите идентификатор приложения и секрет приложения и укажите URL-адрес обратного вызова, перейдя в « Настройки» и указав URL-адрес сайта в разделе « Веб-сайт » для приложения. Также не забудьте ввести действительный адрес электронной почты в поле Контактный адрес электронной почты . Требуется, чтобы иметь возможность сделать это приложение общедоступным и доступным для общественности.

Затем перейдите в раздел « Статус и обзор » и установите ползунок « Да», чтобы сделать приложение общедоступным. Мы создаем файл конфигурации, fb.js, для хранения этой информации о конфигурации, которая потребуется для подключения к Facebook.

1
2
3
4
5
6
// facebook app settings — fb.js
module.exports = {
  ‘appID’ : ‘<your_app_identifier>’,
  ‘appSecret’ : ‘<your_app_secret>’,
  ‘callbackUrl’ : ‘http://localhost:3000/login/facebook/callback’
}

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

1
passport.use(‘facebook’, new FacebookStrategy({ clientID : fbConfig.appID, clientSecret : fbConfig.appSecret, callbackURL : fbConfig.callbackUrl }, // facebook will send back the tokens and profile function(access_token, refresh_token, profile, done) { // asynchronous process.nextTick(function() { // find the user in the database based on their facebook id User.findOne({ ‘id’ : profile.id }, function(err, user) { // if there is an error, stop everything and return that // ie an error connecting to the database if (err) return done(err); // if the user is found, then log them in if (user) { return done(null, user); // user found, return that user } else { // if there is no user found with that facebook id, create them var newUser = new User(); // set all of the facebook information in our user model newUser.fb.id = profile.id; // set the users facebook id newUser.fb.access_token = access_token; // we will save the token that facebook provides to the user newUser.fb.firstName = profile.n

Теперь нам нужно добавить определенные маршруты для включения входа через Facebook и для обработки обратного вызова после того, как пользователь разрешил приложению использовать свою учетную запись Facebook.

01
02
03
04
05
06
07
08
09
10
11
12
13
// route for facebook authentication and login
// different scopes while logging in
router.get(‘/login/facebook’,
  passport.authenticate(‘facebook’, { scope : ’email’ }
));
 
// handle the callback after facebook has authenticated the user
router.get(‘/login/facebook/callback’,
  passport.authenticate(‘facebook’, {
    successRedirect : ‘/home’,
    failureRedirect : ‘/’
  })
);

Страница входа в наше демонстрационное приложение выглядит следующим образом:

Войти через Facebook или Twitter

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

Facebook Auth - Предоставить разрешения

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

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

Аналогичный модуль аутентификации должен быть подключен для обработки аутентификации через Twitter, а Passport встроен, чтобы помочь с его модулем passport-twitter .

Во-первых, вам нужно создать новое приложение Twitter, используя его интерфейс управления приложениями . Здесь следует отметить одну вещь: при указании URL-адреса обратного вызова Twitter, похоже, не очень хорошо с ним работает, если в поле URL-адрес обратного вызова указано «localhost». Чтобы преодолеть это ограничение при разработке, вы можете использовать специальный адрес обратной связи или «127.0.0.1» вместо «localhost». После создания приложения запишите следующий ключ API и секретную информацию в файле конфигурации следующим образом:

1
2
3
4
5
6
// twitter app settings — twitter.js
module.exports = {
    ‘apikey’ : ‘<your_app_key>’,
    ‘apisecret’ : ‘<you_app_secret>’,
    ‘callbackUrl’ : ‘http://127.0.0.1:3000/login/twitter/callback’
}

Стратегия входа в систему для Twitter является примером TwitterStrategy и это выглядит так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
passport.use(‘twitter’, new TwitterStrategy({
    consumerKey : twitterConfig.apikey,
    consumerSecret : twitterConfig.apisecret,
    callbackURL : twitterConfig.callbackURL
  },
  function(token, tokenSecret, profile, done) {
    // make the code asynchronous
    // User.findOne won’t fire until we have all our data back from Twitter
    process.nextTick(function() {
 
      User.findOne({ ‘twitter.id’ : profile.id },
        function(err, user) {
          // if there is an error, stop everything and return that
          // ie an error connecting to the database
          if (err)
            return done(err);
 
            // if the user is found then log them in
            if (user) {
               return done(null, user);
            } else {
               // if there is no user, create them
               var newUser = new User();
 
               // set all of the user data that we need
               newUser.twitter.id = profile.id;
               newUser.twitter.token = token;
               newUser.twitter.username = profile.username;
               newUser.twitter.displayName = profile.displayName;
               newUser.twitter.lastStatus = profile._json.status.text;
 
               // save our user into the database
               newUser.save(function(err) {
                 if (err)
                   throw err;
                 return done(null, newUser);
               });
            }
         });
      });
    })
);
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
// route for twitter authentication and login
// different scopes while logging in
router.get(‘/login/twitter’,
  passport.authenticate(‘twitter’)
);
 
// handle the callback after facebook has authenticated the user
router.get(‘/login/twitter/callback’,
  passport.authenticate(‘twitter’, {
    successRedirect : ‘/twitter’,
    failureRedirect : ‘/’
  })
);
 
/* GET Twitter View Page */
router.get(‘/twitter’, isAuthenticated, function(req, res){
  res.render(‘twitter’, { user: req.user });
});

Теперь, чтобы проверить это, обязательно используйте http://127.0.0.1: <port> вместо использования http://localhost :<port> . Как мы уже упоминали выше, кажется, что существует проблема при обмене токенов с Twitter с «localhost» в качестве имени хоста. При нажатии на кнопку « Войти через Twitter» , как и ожидалось, он запрашивает согласие пользователя на разрешение этому приложению использовать Twitter.

Twitter Auth - Предоставить разрешения

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

И у вас это есть !! Мы успешно добавили логины Facebook и Twitter в наше примерное приложение без написания большого количества кода и обработки сложностей, связанных с механизмом аутентификации, позволяя Passport выполнять тяжелую работу. Подобные стратегии входа могут быть написаны для множества провайдеров, которые поддерживает Passport Код для всего приложения можно найти в этом репозитории git . Не стесняйтесь расширять его и использовать в своих проектах.