8

返回false。從Facebook登錄重定向回調初始成功後,使用passport-facebook 1.0.3和express 4.6。 1,req.session.passport和req.user包含serialize調用期間設置的值(我從stragegy得到的),但在隨後訪問站點上的不同路由時,req.session.passport和req.user爲空,並且req.isAuthenticated()返回false,所以在從FB初始成功登錄後,所有其他路由上的ensureAuthentication方法失敗。 我不使用集羣設置,所以我相信在存儲器存儲足以解決這個問題,Express配置看起來不錯(我指的順序),這裏是我的快速配置req.session.passport和req.user空白,req.isAuthenticated在初次成功登錄後使用passport-facebook

configExpressApp.set('views', './views'); 
configExpressApp.set('view engine', 'jade'); 
configExpressApp.use(morgan('dev')); 
configExpressApp.use(cookieParser()); 
configExpressApp.use(bodyParser.urlencoded({ 
    extended: true, 
})); 
configExpressApp.use(bodyParser.json()); 
configExpressApp.use(expressSession({ 
    secret:'MyExpressSecret', 
    saveUninitialized: true, 
    resave: true 
})); 
configExpressApp.use(passport.initialize()); 
configExpressApp.use(passport.session()); 
configExpressApp.use(methodOverride()); 
configExpressApp.use(express.static('./public')); 

這裏是REQ初始全成登錄和重定向.session對象,該req.user包含相同的數據作爲req.session.passport.user

{ cookie: 
    { path: '/', 
    _expires: null, 
    originalMaxAge: null, 
    httpOnly: true }, 
    passport: 
    { user: 
     { _id: 53ce23e3121421f229a438f8, 
     info: false, 
     loginType: 'fb', 
     fbId: 'MyId', 
     name: 'Karthic Rao', 
     email: '[email protected]' 

     } 
    } 
} 

這是我先前與內部的完成()回調相關聯的信息策略,也在序列化調用中。成功登錄和回調後,我使用res.redirect將用戶重定向到不同的路由,但來自該路由的請求包含sessionID(所以我不認爲它與會話存儲問題),但req.user字段不存在(可能是因爲passport.initialize()和passport.session()中間件不會找到請求進行身份驗證)並且req.session.passport字段爲空,以下是req的console.log中的詳細信息對象。

sessionID: 'I9R1c3PIYgDW5OpWbNT7qb02Hn4lOeAB', 
session: 
    { cookie: 
     { path: '/', 
     _expires: null, 
     originalMaxAge: null, 
     httpOnly: true }, 
    passport: {} }, 

這裏是我的反序列化方法

passport.deserializeUser(function(user, done) { 
    console.log('deserialize loginType facebook'); 
    db.collection("users").findOne({ 
     fbId: user.id 
    }, function(err, docs) { 
     console.log(docs); 
     done(err, docs); 
    }); 
}); 

這裏是我的序列化方法

passport.serializeUser(function (user, done) { 
    console.log(user); 
    done(null, user); 
}); 

這是創造一個偉大的阻礙我的發展,我怎麼能排序了這一點?

+0

嗯...我沒有立即的解決方案來推薦你,但你能告訴我們你的'serializeUser'和'deserializeUser'方法嗎? 對我來說,它看起來像會話中存儲的任何內容都沒有正確反序列化。 –

+0

我編輯了這個問題,在問題結尾添加了我的序列化和反序列化方法。謝謝你的回覆! –

+0

我也注意到,在後續請求中發送給反序列化方法的'user'對象是'null'! –

回答

9

那麼,如果你可以在你使用策略的地方添加代碼(它應該在中間件中),那會給我們一個完整的問題視圖,因爲我們需要知道什麼對象發送到serializeUser

(非常)基本上,當用戶嘗試進行身份驗證,事情發生這樣的:

  • 護照試圖對Facebook的服務器上的用戶進行身份驗證
  • 如果成功,則回調函數(或successRedirect)被稱爲 包含用戶的詳細信息的對象
  • 然後,護照使得以req.login調用存儲一些信息關於 用戶在會話
  • 然後serializeUser被調用並有效存儲您在會話中指定的數據

但是,從您發佈的代碼中,我懷疑在您的deserializeUser,用戶。ID未定義,因爲存儲在會話中的user對象使用名爲_id而不是ID的ID字段。

如果更改

db.collection("users").findOne({ 
     fbId: user.id 

db.collection("users").findOne({ 
     fbId: user._id 

db.collection("users").findById(user._id, [fields],[options],[callback]); 

,我認爲它應該工作。

編輯:我根據@ BrandonZacharie的評論編輯了我的答案,該評論在我的代碼中指出了一個錯誤。

+0

不應該是「... findOne({fbId:user.fbId} ...」或「... findOne({_id:mongodb.ObjectId(user._id)} ...」而不是? –

+0

@ BrandonZacharie我重新閱讀了你的評論(並刪除了我之前的評論,因爲它是錯誤的)我認爲你是對的,我只是複製粘貼了Karthic Rao的代碼而沒有留意,Mongoose甚至有一個[findById方法](http:///mongoosejs.com/docs/api.html#model_Model.findById),它接受一個「objectid或可以被轉換爲一個值」作爲它的第一個參數。 如果沒關係,我會根據你的建議編輯我的答案與你(或你可以發表你的評論作爲答案) –

+1

是的_id提交被稱爲ID是肯定的問題之一,但另一個問題是,我在後端使用requirejs模塊化和nodejs代碼,我使用不同的護照對象配置爲中間件(passport.session()和護照)的錯誤.initialize()),並且我在不同的護照對象上調用了serializeUser和deserializeUser。現在它的工作,感謝你爲幫助我而做出的所有努力! –

相關問題