18 July 2015

Тонкости работы с PassportJs

Website developmentJavaScriptNode.JS
Недавно работая над очередным проектом, который использует 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 - то что нужно!
  }
));


Пока все.
Tags:passport.jsexpress.jspassport-facebookpassport-vkontaktejavascriptnode.js
Hubs: Website development JavaScript Node.JS
-3
9.6k 55
Comments 8
Top of the last 24 hours