I am using passport JS, express and mongoose to make an API. When I test it in same domain it maintain session and works fine. But in cross domain it fails. Any clue how can i maintain the session in cross domain using the same configuration. Following is the code
我使用护照JS,express和mongoose来制作API。当我在同一个域中测试它时,它保持会话并正常工作。但在跨域中它失败了。任何线索如何使用相同的配置在跨域维护会话。以下是代码
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);
});
3 个解决方案
#1
7
I was having the same problem. Before configuring anything in express app, use the following(exactly the same) to set header of response for cross-domain :
我遇到了同样的问题。在快速应用程序中配置任何内容之前,请使用以下(完全相同)为跨域设置响应标头:
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();
}
});
It works for me. Best of luck!
这个对我有用。祝你好运!
#2
4
As per Sriharsha's answer:
根据Sriharsha的回答:
-
Set
res.header("Access-Control-Allow-Credentials", "true");
设置res.header(“Access-Control-Allow-Credentials”,“true”);
-
Make sure you pass the credentials in the client side call. For example for AJAX, add this to your call:
xhrFields: {withCredentials: true},
确保在客户端呼叫中传递凭据。例如,对于AJAX,将其添加到您的调用中:xhrFields:{withCredentials:true},
Additionally:
另外:
-
Don't use the wildcard for Access-Control-Allow-Origin with a credentialed request
不要使用带有凭证请求的Access-Control-Allow-Origin通配符
As explained on MDN:
如MDN所述:
when responding to a credentialed request, server must specify a domain, and cannot use wild carding
在响应凭证请求时,服务器必须指定域,并且不能使用通配符
I use this file, and call it from my main module with require("./enable-cors.js")(app);
我使用这个文件,并使用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
};
#3
2
Allow the credentials to be shared by setting Access-Control-Allow-Credentials header. (I am not sure why you have commented in your code)
通过设置Access-Control-Allow-Credentials标头允许共享凭据。 (我不确定你为什么评论你的代码)
res.header("Access-Control-Allow-Credentials", "true");
then pass the credentials from javascript through XHR object.
然后从javascript通过XHR对象传递凭据。
xhr.withCredentials = true;
#1
7
I was having the same problem. Before configuring anything in express app, use the following(exactly the same) to set header of response for cross-domain :
我遇到了同样的问题。在快速应用程序中配置任何内容之前,请使用以下(完全相同)为跨域设置响应标头:
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();
}
});
It works for me. Best of luck!
这个对我有用。祝你好运!
#2
4
As per Sriharsha's answer:
根据Sriharsha的回答:
-
Set
res.header("Access-Control-Allow-Credentials", "true");
设置res.header(“Access-Control-Allow-Credentials”,“true”);
-
Make sure you pass the credentials in the client side call. For example for AJAX, add this to your call:
xhrFields: {withCredentials: true},
确保在客户端呼叫中传递凭据。例如,对于AJAX,将其添加到您的调用中:xhrFields:{withCredentials:true},
Additionally:
另外:
-
Don't use the wildcard for Access-Control-Allow-Origin with a credentialed request
不要使用带有凭证请求的Access-Control-Allow-Origin通配符
As explained on MDN:
如MDN所述:
when responding to a credentialed request, server must specify a domain, and cannot use wild carding
在响应凭证请求时,服务器必须指定域,并且不能使用通配符
I use this file, and call it from my main module with require("./enable-cors.js")(app);
我使用这个文件,并使用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
};
#3
2
Allow the credentials to be shared by setting Access-Control-Allow-Credentials header. (I am not sure why you have commented in your code)
通过设置Access-Control-Allow-Credentials标头允许共享凭据。 (我不确定你为什么评论你的代码)
res.header("Access-Control-Allow-Credentials", "true");
then pass the credentials from javascript through XHR object.
然后从javascript通过XHR对象传递凭据。
xhr.withCredentials = true;