2013-09-27 104 views
8

我使用Passport JS,express和mongoose來創建API。當我在同一個域中測試它時,它會保持會話並正常工作。但是在跨域中它失敗了。任何線索我怎樣才能維持跨域使用相同的配置會話。以下是代碼Passport js無法在跨域中維護會話

allowCrossDomain = function(req, res, next) { 
    res.header("Access-Control-Allow-Origin", "*"); 
    res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); 
    res.header("Access-Control-Allow-Headers", req.headers["access-control-request-headers"]); 
    // res.header("Access-Control-Allow-Credentials", "true"); 
    if ("OPTIONS" == req.method) { 
     res.send(200); 
    } else { 
     next(); 
    } 

    //allow all crossDomain request 
app.use(allowCrossDomain); 

//session handling 
app.use(express.cookieParser("gallery")); 
app.use(express.session()); 
app.use(passport.initialize()); 
app.use(passport.session()); 

app.use(function(req, res, next) { 
    // check if client sent cookie 
    var cookie = req.cookies.cokkieName; 
    if (cookie === undefined) { 
     //set up cookie here by a random number 
     }); 
    } 
    next(); // <-- important! 
}); 
passport.use(new LocalStrategy({ 
    usernameField: "email" 
}, 
function(email, password, done) { 
    User.authenticate(email, password, function(err, reply) { 
     //authenticate user and call the callback 
      return done(err, false); 

    }); 
})); 


passport.serializeUser(function(user, done) { 
return done(null, user._id); 
}); 


passport.deserializeUser(function(id, done) { 
//find user via id and return the user details 
return done(null, user._id); 
}); 

    app.post("/login", function(req, res, next) { 
    passport.authenticate("local", 
     function(err, data, info) { 
      //custom callback 
      user.getProfile(req, res, next, err, data, info); 
     })(req, res, next); 
}); 
+0

叫它@ kundu_你有解決方案嗎? –

回答

2

允許憑證通過設置共享接入控制允許憑據報頭。 (我不知道爲什麼你在你的代碼有評論)

res.header("Access-Control-Allow-Credentials", "true"); 

然後pass the credentials從JavaScript通過XHR對象。

xhr.withCredentials = true; 
6

我遇到了同樣的問題。之前在快遞應用任何配置,使用以下(完全一樣)來設置響應跨域的標題:

app.use(function(req, res, next) { 
res.header('Access-Control-Allow-Credentials', true); 
res.header('Access-Control-Allow-Origin', req.headers.origin); 
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); 
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept'); 
if ('OPTIONS' == req.method) { 
    res.send(200); 
} else { 
    next(); 
} 
}); 

這對我的作品。祝你好運!

+0

你知道它爲什麼要這樣嗎?爲什麼需要憑證? –

+0

你太棒了。我爲此浪費了6個小時。謝謝你 –

+0

我也面臨同樣的問題,這個解決方案仍然不適合我。我該怎麼辦?請幫忙。 –

4

按斯里莎的回答是:

  • res.header("Access-Control-Allow-Credentials", "true");

  • 確保你通過在客戶端調用的憑據。例如,對於AJAX,它添加到您的來電:xhrFields: {withCredentials: true},

此外:

  • 不要使用訪問控制允許來源通配符有資格的請求

    由於explained on MDN

    當響應一個資格的請求,服務器必須指定一個 域,而不能使用野生梳理


我使用這個文件,並從我的主要模塊require("./enable-cors.js")(app);

// enable-cors.js 
module.exports = function(app) { 

    var methodOverride = require('method-override') 
    app.use(methodOverride()); 
    var allowCrossDomain = function(req, res, next) { 
     res.header('Access-Control-Allow-Credentials', true); 
     res.header('Access-Control-Allow-Origin', req.headers.origin); 
     res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); 
     res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); 

     // intercept OPTIONS method 
     if ('OPTIONS' == req.method) { 
      res.send(200); 
     } 
     else { 
      next(); 
     } 
    }; 
    app.use(allowCrossDomain); 
    // Built upon: http://cuppster.com/2012/04/10/cors-middleware-for-node-js-and-express/#sthash.WdJmNaRA.dpuf 

}; 
+0

非常感謝。 –