2012-06-12 2 views
6

Я пытаюсь интегрировать паспорт на свой сервер nodejs, используя connect, но не могу сделать это правильно. Все руководства/примеры используют expressJS, поэтому я изо всех сил старался переформатировать код для работы с моим кодом, но я не могу заставить его работать. Связанные части написаны ниже. Есть ли у кого-нибудь советы о том, что может быть проблемой? passport.authenticate() никогда не кажется вызванным (по крайней мере, сообщение console.log в обратном вызове аутентификации facebook никогда не печатается). В настоящее время я ничего не сохраняю в базе данных, поэтому проблема, надеюсь, будет чем-то действительно простым, что я просто не вижу.Использование PassportJS с Connect для NodeJS для аутентификации пользователей Facebook

Единственное, что приходит на ум - это потенциальный обратный вызов, который у меня есть для facebook, который является URL-адресом localhost (так как я все еще разрабатываю это локально). Я смог аутентифицироваться с помощью facebook просто отлично, используя everyauth (из чисто локального экземпляра), но переключился на паспортный код, так как у меня были разные проблемы, которые, по-видимому, обращались в паспорт.

passport = require('passport'); 
    fpass = require('passport-facebook').Strategy; 

passport.serializeUser(function(user,done){ 
    done(null, user); 
}); 
passport.deserializeUser(function(obj,done){ 
    done(null,obj); 
}); 

passport.use(new fpass({ 
     clientID:'facebook app id', 
     clientSecret:'facebook app secret', 
     callbackURL:'http://localhost:3000/auth/facebook/callback' 
    }, 
    function(accessToken, refreshToken, fbUserData, done){ 
     console.log('got here'); 
     return done(null,fbUserData); 
    } 
)); 



    function checkLoggedIn(req, res, next){ 
     console.log("req.user: " + req.user); 
     if(req.user) 
      next(); 
     else{ 
      console.log('\nNot LOGGED IN\n'); 
      if(req.socket.remoteAddress || req.socket.socket.remoteAddress == '127.0.0.1'){ 
       var folder,contentType; 
       console.log('req url = '+req.url); 
       if(req.url == '/'){ 
        folder = __dirname + '/landingPage.html'; 
        contentType = 'text/html'; 
       } 
       else if(req.url == '/auth/facebook'){ 
        passport.authenticate('facebook'); 
        return; 
       } 
       else if(req.url == '/auth/facebook/callback'){ 
        passport.authenticate('facebook', {failureRedirect: '/failbook', successRedirect:'/'}); 
        return; 
       } 
       if(folder){ 
        console.log('got to folder part\n\n'); 
        fs.readFile(folder, function(error, content){ 
         if(error){ 
         res.writeHead(500); 
         res.end(); 
         } 
         else{ 
         res.writeHead(200, {'Content-Type': contentType}); 
         res.end(content); 
         } 
        }); 
        } 
        else{ res.writeHead(500); res.end();} 
      } 
      else {res.writeHead(500); res.end();} 
     } 
    } 

    connect.createServer(
    connect.cookieParser(), 
    connect.bodyParser(), 
    connect.session({secret:'wakajakamadaka'}), 
    passport.initialize(), 
    passport.session(), 
    checkLoggedIn).listen(8888); 
    console.log('Server has started.'); 
} 

Есть ли у кого-нибудь какие-либо советы или есть сбой в том, что я делаю? Мои другие две альтернативы возвращаются к everyauth и выясняют, что там происходит, или переключаясь на ExpressJS, но я бы не пошел ни с одним из этих вариантов.

Бест
Сами

ответ

8

passport.authenticate возвращает функцию, которая обычно используется в цепи промежуточного слоя, который вызывается, с req и res курьерским.

Он будет работать автономно внутри другого промежуточного или обработчика маршрута, такие как ваша checkLoggedIn функции, но вы должны явно вызвать функцию возвращается с req, res и next позволить ему обработать запрос.

else if(req.url == '/auth/facebook'){ 
    // NOTE: call the function returned to process the request 
    passport.authenticate('facebook')(req, res, next); 
    return; 
} 

Выглядит неплохо. Дай мне знать, если ты будешь работать.


UPDATE

Джаред помог мне немного вне StackOverflow, и мы выяснили проблему полностью. Я обновляю этот ответ, чтобы включить новую информацию, которую мы нашли.


1) Один вопрос, очевидно, что редирект() промежуточный слой существует Экспресс, но не в Connect (по крайней мере, не текущая версия). При использовании подключения, вам необходимо строка 97 из authenticate.js изменить в модуле PassportJS от return res.redirect(options.successRedirect); к:

var redirect = function(redirectionURL){ 
    res.writeHead(302, {'location':redirectionURL}); 
    res.end();    
} 

return redirect(options.successRedirect); 

примечание - options.successRedirect выше, является такой же, как successRedirect в функции обратного вызова кода. Это будет строка passport.authenticate('facebook', {failureRedirect: '/failbook', successRedirect:'/'}); в коде в моем вопросе.


2) Другая в том, что я использую модуль кластера в мое приложение (не то, что показывает в моем фрагменте кода выше). Это означает, что приложение sessionJS не читается должным образом, что привело к моим проблемам. Эта проблема затронет любую библиотеку, которая полагается на сеансы, включая все другие модули аутентификации, которые используют сеансы (например, everyauth, connect-auth и т. Д.).) Процитирую Джаред для решения:

Quick reply: are you using cluster or spinning up multiple server instances?

If so, the built-in MemoryStore for the session won't work properly, and you need to switch to something like this: https://github.com/visionmedia/connect-redis

Or one of the other session stores listed here: https://github.com/senchalabs/connect/wiki

The reason is that you'll end up hitting a server which didn't serve the original request, and thus doesn't have that session information in its own memory. That sounds like what could be going on if deserializeUser isn't called 100% of the time.

Надеется, что это помогает, кто делает это здесь!

+0

Хмм я добираюсь дальше, чем раньше, но пока не совсем работает. теперь я регистрирую обратный вызов из facebook. Я проверяю '/ auth/facebook/callback' на req.url.split ('?') [0] сейчас, чтобы обратный вызов регистрировался. добавление (req, res, next) после вызова функции вызывает бесконечный цикл переадресации. есть идеи? – thisissami

+0

Я думаю, вам нужно использовать промежуточное программное обеспечение 'connect.query()' в настройке промежуточного программного обеспечения 'createServer'. Паспорт ожидает, что 'req.query' будет заполнен во многих случаях, включая получение кода авторизации в обратном вызове Facebook. –

+0

почти там ... с добавлением '(req, res, next)', добавленным в конец вызова аутентификации обратного вызова, функция ответа на facebook достигается с использованием соответствующих данных в facebook. Тем не менее, я получаю 'TypeError: Object # не имеет метода 'redirect''. Оскорбительной строкой кода является 'return res.redirect (options.successRedirect);' в строке 97 authenticate.js. Любая идея, что может быть проблемой? – thisissami

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