4

I hava an issue ussing Passport: I'm not being able to check if a user is authenticated when calling my custom endpoints.

I have configured my Express4 application in the following way:

app.use(morgan('dev')); // log every request to the console
app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// required for passport
app.use(session({ secret: 'secretphrase' })); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(checkAuth); // CHECK SESSION
app.use(flash()); // use connect-flash for flash messages stored in session
app.use(prepareRequests);

The checkAuth() middleware has the following code:

var checkAuth = function(request, response, next) {

    console.log("------------");
    console.log("checkAuth user: " + request.session.passport.user);
    console.log("checkAuth isAuthenticated: " + request.isAuthenticated());
    next();
}

The first time I try to login with passport, isAuthenticated is false. Once I'm logged in, every call I do to my server, when passing thorugh my middleware, isAuthenticated is false too!!! But, the strange thing is that if I try to login again, isAuthenticated is true.

That means that only my AJAX calls return isAuthenticated = false, but when I maka a form post or click on a link to the API, it return true! Then the session is stored, but not for the AJAX request.

What I'm doing wrong? Are the cookies not being passed?

Yangshun Tay
  • 49,270
  • 33
  • 114
  • 141
Jorge Miranda
  • 231
  • 1
  • 10
  • You're going to have to include how you set up Passenger's `serializeUser` and `deserializeUser` methods, as well as what strategy you are using. – AlbertEngelB Sep 08 '14 at 19:59
  • As I told you, in the next calls serializeUser and deserializeUser are getting called, with both local and google strategies. – Jorge Miranda Sep 08 '14 at 20:04
  • I notice that no Cookies are being mpassed in my AJAX calls... I supouse that the cookie is needed to check the session... – Jorge Miranda Sep 08 '14 at 20:05
  • I don't know, sounds like an issue with how you are doing the logins if anything [(assuming you aren't using a seperate domain).](http://stackoverflow.com/questions/2870371/why-is-jquerys-ajax-method-not-sending-my-session-cookie) The request should be using the same cookies and sessions as your other requests; shouldn't matter if it is an AJAX request or not. – AlbertEngelB Sep 08 '14 at 20:11

2 Answers2

7

Seems that talking to Dropped.on.Caprica helps me to find the solution....

The server was logged in and saving the session succesfully. But, then, you must pass the cookie (withCredentials = true)created by Express in the following AJAX request. If you are using JQuery, in the following way:

$.ajax({
    url: 'http://127.0.0.1:3003/users/me',
    type: 'GET',
    xhrFields: {
       withCredentials: true
    }}).done(function() {
      alert( "done" );
    });

If you are not:

var request = window.XDomainRequest ? new XDomainRequest() : new XMLHttpRequest();      
var pda;
request.withCredentials = true;

Then, on every call, in your Node.JS server, asking for request.isAuthenticated() will return the right value!!!

Other tip: Don't forget to modify your response headers in the Express response to allow credentials and specify the origin to make it work in Chrome:

response.header("Access-Control-Allow-Credentials", "true");
response.header("Access-Control-Allow-Origin", "http://127.0.0.1:3008");
Jorge Miranda
  • 231
  • 1
  • 10
0

If you're using fetch:

fetch('/my/url', { 
  method: 'GET',
  credentials: 'same-origin',
})
.then(res => res.json())
.then(...);

Read more at MDN Fetch

Yangshun Tay
  • 49,270
  • 33
  • 114
  • 141