Reputation: 5445
I'm new to using Express and Connect, so I'm hoping I'm doing something stupid that has a simple solution.
Basically, I have a page where a user logs in using Persona. To validate authentication attempts, I use express-persona. Supposedly, this module saves the user's validated email address in a session variable (req.session.email, by default).
Now, after logging in, users can post a comment, and this comment will be saved together with the email address with which the user logged in. When the server that serves the form is the same as the one that handles the posting of the comment, this works fine. However, when they are different (let's say the user fills in the form at http://localhost:8001
, whereas the browser then sends a POST request to http://localhost:8000
which should save the comment), all of a sudden the req.session.email value is undefined
.
I think I set up Cross-Origin Resource Sharing correctly. The form is sent thusly (using jQuery):
$.ajax('http://localhost:8000/post/comment',
{
data: {comment: $('#commentField').val()},
type: 'POST',
xhrFields: {withCredentials: true}
}
);
(Note the xhrField: {withCredentials: true}
-- the session cookie is passed along, which I verified by inspecting the network request.)
The server sets up the (I think) correct CORS headers:
res.header('Access-Control-Allow-Origin', 'http://localhost:8001');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
res.header('Access-Control-Allow-Credentials', 'true');
When I add console.log(req.cookie)
, I see the sessionId
cookie that has the same value as the one sent along with the POST request.
However: console.log(req.session.email)
displays undefined
for cross-origin requests -- again, it works fine when the requests come from the same origin.
What am I doing wrong?
Upvotes: 2
Views: 5210
Reputation: 1917
For those who are looking to solve the same problem with Angular implementations. You can configure $http to send cookies using:
.config(function ($routeProvider, $httpProvider) {
$httpProvider.defaults.withCredentials = true;
//rest of route code
Upvotes: 3
Reputation: 5445
I found out my problem: I forgot to send cookies with the authentication request. Hence, the Express server could not identify the current user's session when logging in, and consequently could not save the user data to the session.
The solution was to also send the Persona assertion request with the withCredentials
flag, as such:
var response = $.ajax(assertionUrl + '/verify', {
data: {assertion: assertion},
type: 'POST',
xhrFields: {withCredentials: true}
});
(I don't think anyone will ever run into this exact same problem, but just in case...)
Upvotes: 7