2015-09-16 3 views
3

После нескольких часов, пытаясь решить это самостоятельно, я добираюсь до сообщества SO, ищущего некоторый свет.Ответ на проверку подлинности паспорта

Я использую паспорт для аутентификации пользователей. Это уже инициализирован в моем главном файле express.js в соответствии с Документами:

app.use(passport.initialize()); 

Я получил index.js файл, который обрабатывает facebook-passport таким образом: index.js

'use strict'; 

import express from 'express'; 
import passport from 'passport'; 
import auth from '../auth.service'; 
let router = express.Router(); 

//this function is defined in the auth.service import but copied it here in case it's needed (the `signToken` is also defined in the service) 
function setTokenCookie(req, res) { 
    if (!req.user) return res.json(404, { message: 'Something went wrong, please try again.'}); 
    var token = signToken(req.user._id, req.user.role); 
    res.cookie('token', JSON.stringify(token)); 
    res.redirect('/'); 
} 


router 
    .get('/', passport.authenticate('facebook', { 
    scope: ['email', 'user_about_me'], 
    failureRedirect: '/login' 
    })) 

.get('/callback', passport.authenticate('facebook', { 
    successRedirect: '/', 
    failureRedirect: '/login' 
}), setTokenCookie); 

module.exports = router; 

и паспорт .js, который импортируется в index.js таким образом:

passport.js

import passport from 'passport'; 
import { 
    Strategy as FacebookStrategy 
} 
from 'passport-facebook'; 

exports.setup = function(User, config) { 
    passport.use(new FacebookStrategy({ 
     clientID: config.facebook.clientID, 
     clientSecret: config.facebook.clientSecret, 
     callbackURL: config.facebook.callbackURL 
    }, 
    function(accessToken, refreshToken, profile, done) { 
     User.findOne({ 
     'facebook.id': profile.id 
     }, (findErr, user) => { 
     if (findErr) { 
      return done(findErr); 
     } 
     if (!user) { 
      let userToSave = new User({ 
      name: profile.displayName, 
      email: profile.emails[0].value, 
      role: 'user', 
      username: profile.username, 
      provider: 'facebook', 
      facebook: profile._json 
      }); 
      userToSave.save((saveErr) => { 
      if (saveErr) done(saveErr); 
      return done(null, user); 
      }); 
     } else { 
      return done(null, user); 
     } 
     }); 
    } 
)); 
}; 

Это то, что в настоящее время происходит:

  • Facebook Войти предлагается
  • После успешной аутентификации в Facebook обратного вызова (/ авториз/facebook/обратный вызов) достигается с информацией пользователя и лексема, как ожидалось.
  • Пользователь сохраняется в БД с ожидаемыми полями

Где вещи получают странно:

  • После сохранения пользователем, done(null,user) не делает ничего. Приложение зависает при обратном вызове, и клиент продолжает ждать ответа.
  • Средство промежуточного программного обеспеченияTokenCookie никогда не вызывается, поэтому проблема определенно находится на предыдущем шаге.

Что я пробовал:

  • Обертывание всю функцию установки из passport.js в process.tick (нашел некоторые люди используют его, но не решить эту проблему)
  • Использование Мангуст с как в User.findOne({...}).exec().then(user => {...})

Если вам нужна дополнительная информация, пожалуйста, не стесняйтесь спрашивать. Любая помощь действительно ценится.

Спасибо!

+0

Вы звоните в mongoose.connect()? –

+0

Да :). Все, что касается Mongoose, работает, как ожидалось, пользователь либо сохраняется, либо извлекается из БД, но в обоих случаях, когда это делается (нуль, пользователь), он называется зависанием. – Daniel

+0

Как вы определяете, что setTokenCookie не выполняется? У вас просто есть console.logs повсюду? –

ответ

0

Я вижу несколько возможных недостающих частей, взглянув на мой код. Используете ли вы промежуточное ПО passport.session()? Также функции serializeUser и deserializeUser?

passport.serializeUser(function(user, done) { 
    //place user's id in cookie 
    done(null, user.id); 
}); 

passport.deserializeUser(function(id, done) { 
    //retrieve user from database by id 
    User.findById(id, function(err, user) { 
    done(err, user); 
    }); 
}); 
+0

Здравствуйте @cody. Да, я попытался использовать 'pass.session()', а также удалить его и добавить параметр '{session: false}' в стратегию Passport. Что касается этих функций, были ли они вызваны Необходимы ли они? – Daniel

+0

'serializeUser' будет вызываться после того, как пользователь успешно войдет в систему через facebook, чтобы сделать user.id доступным в cookie для последующих запросов.' DeserializeUser' используется для последующих запросов, чтобы вы могли получить пользователя из вашего хранилища данных. Я считаю, что вы хотите использовать их в своем сценарии с помощью «промежуточного программного обеспечения« pass.session() ». Я уверен, что паспорт ожидает, что они будут использоваться для всего, кроме служб, по которым вы отправляете учетные данные для каждого запроса (обычно API). –

Смежные вопросы