Недавно работая над очередным проектом, который использует passporjs, наткнулся на несколько проблем, с которыми в интернете сталкивались и другие разработчики. Но ответов в интернете я не нашел (возможно плохо искал).

Расскажу об этих проблемах и как их решал.

Документация по PassportJS и его 3-d Strategy вроде достаточно для старта, но в ходе разработки у меня возникли такие проблемы:
1. facebook не предоставлял те поля, которые мне нужны, например, email
2. vkontakte, тоже не предоставлял email, но уже по другой причине, нежели чем facebook

И так, решаем первую проблему.
В документации сказано, что scope, надо передавать в options, при выполнении собственно авторизации:
app.get('/auth/facebook/callback',
  passport.authenticate('facebook', { failureRedirect: '/login', scope: [
                        'email',
                        'publish_actions',
                        'user_friends',
                        'user_about_me',
                        'user_birthday'
                    ] }),
  function(req, res) {
    // Successful authentication, redirect home.
    res.redirect('/');
  });


Но, email не возвращался все равно. В итоге продебажив исходники, стало ясно, что scope, надо передавать в настройках самой Strategy, разделяя их запятой:
passport.use(new FacebookStrategy({
    clientID: FACEBOOK_APP_ID,
    clientSecret: FACEBOOK_APP_SECRET,
    callbackURL: "http://localhost:3000/auth/facebook/callback",
    scope: 'email',
    enableProof: false
  },
  function(accessToken, refreshToken, profile, done) {
    User.findOrCreate({ facebookId: profile.id }, function (err, user) {
      return done(err, user);
    });
  }
));


Собственно все заработало.

2. Но, проблема с использованием passport-vkontakte, не решилась, тк вконтакте особенный и отдает email не в профиле пользователя, а сразу при запросе access_token. Начал ковырять исходники более глубоко. В итоге нашел такой кусок кода в passport-oauth2:
if (arity == 5) {
     self._verify(accessToken, refreshToken, params, profile, verified);
 } else { // arity == 4
    self._verify(accessToken, refreshToken, profile, verified);
 }

Собственно, это говорит о том, что можно передать callback верификации с 5ю параметрами и туда придет в params сырой ответ вконтакте при получении accessToken:
passport.use(new VKontakteStrategy({
    clientID:     VKONTAKTE_APP_ID, // VK.com docs call it 'API ID'
    clientSecret: VKONTAKTE_APP_SECRET,
    callbackURL:  "http://localhost:3000/auth/vkontakte/callback"
  },
  function(accessToken, refreshToken, params, profile, done) {
    //params.email - то что нужно!
  }
));


Пока все.
Были ли такие же проблемы?

Проголосовало 33 человека. Воздержалось 63 человека.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Комментарии (7)


  1. zelenin
    19.07.2015 01:17
    +5

    все, работая со сторонними библиотеками, сталкиваются с неточностями в документации и недокументированными фичами/методами/хаками.


    1. ekubyshin Автор
      19.07.2015 02:05
      -5

      Проницательно…


  1. uSide
    19.07.2015 02:22

    2 «проблема» это сильно, учитывая, что в examples именно так и написано юзать


    1. ekubyshin Автор
      19.07.2015 08:19
      -2

      И что там написано? Посмотри различия


    1. ekubyshin Автор
      19.07.2015 08:23
      -3

      А тебя не смущает экзампл? Он для Фейсбука сделан, автору было лень свой экзампл написть, ну либо хотя бы пару строк поправить в нем


      1. uSide
        19.07.2015 20:04
        -1

        Боже мой, да какая разница? Там показан общий паттерн, почему бы не следовать ему?


        1. ekubyshin Автор
          19.07.2015 21:04

          Может потому что он не совсем рабочий для вк? Ты видел в чем отличие то?