2012-06-12 31 views
6

Tôi đang cố gắng tích hợp hộ chiếu vào máy chủ nodejs của tôi bằng cách sử dụng kết nối, nhưng dường như không thể làm điều đó đúng cách. Tất cả các hướng dẫn/ví dụ sử dụng expressJS, vì vậy tôi đã cố gắng hết sức để định dạng lại mã để làm việc với mã của mình, nhưng tôi dường như không thể làm cho nó hoạt động được. Các phần liên quan được viết dưới đây. Có ai có lời khuyên nào về những gì có thể là vấn đề? passport.authenticate() không bao giờ có vẻ được gọi (ít nhất là thông điệp console.log trong cuộc gọi xác thực facebook không bao giờ in). Tôi hiện đang không lưu bất cứ thứ gì vào cơ sở dữ liệu, do đó, vấn đề hy vọng sẽ là một cái gì đó thực sự đơn giản mà tôi chỉ thiếu.Sử dụng PassportJS với Kết nối cho NodeJS để xác thực Người dùng Facebook

Điều duy nhất mà nói đến cái tâm là tiềm năng gọi lại tôi có cho facebook, đó là một url localhost (kể từ khi tôi vẫn đang phát triển này tại địa phương). Tôi đã có thể xác thực với facebook tốt bằng cách sử dụng everyauth (từ một trường hợp hoàn toàn địa phương), nhưng chuyển sang passportJS kể từ khi tôi đã có vấn đề khác nhau có hộ chiếuJS dường như địa chỉ.

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.'); 
} 

Có ai có lời khuyên nào hay nhìn thấy sự cố trong những gì tôi đang làm không? Hai lựa chọn thay thế khác của tôi đang chuyển trở lại everyauth và tìm ra những gì đang diễn ra ở đó, hoặc chuyển sang ExpressJS, nhưng tôi không muốn đi với một trong các tùy chọn đó.

nhất,
Sami

Trả lời

8

passport.authenticate trả về một chức năng mà thường được sử dụng trong chuỗi middleware, mà được gọi với reqres bởi Express.

Nó sẽ làm việc độc lập bên trong middleware khác hoặc một handler lộ trình, chẳng hạn như chức năng checkLoggedIn của bạn, nhưng bạn phải gọi một cách rõ ràng chức năng quay trở lại với req, res, và next để cho nó xử lý yêu cầu.

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

Có vẻ tốt khác. Hãy cho tôi biết nếu điều đó giúp bạn và chạy.


CẬP NHẬT

Jared đã giúp tôi một chút bên ngoài của stackoverflow, và chúng tôi đã tìm ra vấn đề hoàn toàn. Tôi đang cập nhật câu trả lời này để bao gồm thông tin mới mà chúng tôi đã tìm thấy.


1) Một vấn đề rõ ràng là chuyển hướng() middleware tồn tại trong Express nhưng không Connect (ít nhất không phải là phiên bản hiện tại). Khi sử dụng kết nối, bạn sẽ cần phải thay đổi dòng 97 của authenticate.js trong module PassportJS từ return res.redirect(options.successRedirect); tới:

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

return redirect(options.successRedirect); 

lưu ý - các options.successRedirect trên là giống như successRedirect trong mã hàm callback. Đây sẽ là dòng passport.authenticate('facebook', {failureRedirect: '/failbook', successRedirect:'/'}); trong mã trong câu hỏi của tôi.


2) Cách khác là tôi đang sử dụng mô-đun cụm trong ứng dụng của mình (không phải thứ gì đó hiển thị trong đoạn mã trên). Điều này có nghĩa là dữ liệu phiên không được đọc đúng bởi ứng dụng nodeJS, điều này dẫn đến sự cố của tôi. Sự cố này sẽ ảnh hưởng đến bất kỳ thư viện nào dựa trên phiên, bao gồm tất cả các mô-đun xác thực khác sử dụng các phiên (ví dụ: everyauth, connect-auth, v.v.) Tôi sẽ báo Jared cho một giải pháp:

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.

Hy vọng điều này sẽ giúp ai làm cho nó ở đây!

+0

hmm Tôi đang đi xa hơn tôi trước đây, nhưng nó vẫn chưa hoạt động. bây giờ tôi đang đăng ký cuộc gọi lại từ facebook. Tôi đang kiểm tra '/ auth/facebook/callback' đối với req.url.split ('?') [0] ngay bây giờ để cuộc gọi lại sẽ đăng ký. thêm một (req, res, next) sau khi cuộc gọi hàm gây ra một vòng lặp chuyển hướng vô hạn. bất kỳ ý tưởng? – thisissami

+0

Tôi nghĩ bạn sẽ cần sử dụng phần mềm trung gian 'connect.query()' trong thiết lập phần mềm trung gian 'createServer' của bạn. Hộ chiếu dự kiến ​​'req.query' sẽ được phổ biến trong nhiều trường hợp, bao gồm cả việc nhận mã ủy quyền trong cuộc gọi lại trên Facebook. –

+0

hầu như ở đó ... với một '(req, res, next)' được thêm vào cuối cuộc gọi xác thực gọi lại, chức năng phản hồi facebook được truy cập với dữ liệu facebook thích hợp. Tuy nhiên, tôi nhận được một 'TypeError: Object # không có phương thức 'redirect''. Dòng mã vi phạm là 'return res.redirect (options.successRedirect);' trên dòng 97 của authenticate.js. Vấn đề là gì vậy? – thisissami

Các vấn đề liên quan