3

My issue is similar to this one, all answers there didnt help me.

I'm using Passport.js with local strategy (passport-local-mongoose). The middleware below works on Postman but fails whenever I try from my React client.

exports.isLoggedIn = (req, res, next) => {
  console.log(req.user) // undefined with react, but works from postman
  if (req.isAuthenticated()) {
    return next();
  }
}

Here's my app.js:

require('./handlers/passport');
app.use(cors())
app.use(session({
  secret: process.env.SECRET,
  key: process.env.KEY,
  resave: true,
  saveUninitialized: true,
  store: new MongoStore({ mongooseConnection: mongoose.connection })
}));
app.use(passport.initialize());
app.use(passport.session());

handlers/passport.js:

const passport = require('passport');
const mongoose = require('mongoose');
const User = mongoose.model('User');

passport.use(User.createStrategy());

passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

user.js (model):

...
userSchema.plugin(passportLocalMongoose, { usernameField: 'email' });

CLIENT CODE:

const url = 'http://localhost:7777/users/<id>';
const config = {
  headers: {
    'Content-Type': 'application/json',
  },
};

axios.put(url, data, config)
  .then(res => console.log(res))
  .catch(err => console.log(err));

Am I missing something? does passportLocal strategy means that I can't use with an API and a client like my example? Thanks :D

Jean Bauer
  • 101
  • 1
  • 7
  • 1
    Show your code where you send request to the server in React app. – alexmac Aug 06 '17 at 21:39
  • There's nothing different from a normal http call. I'm using axios.js without sending any headers, I already tried with const headers = { credentials: 'include' }; – Jean Bauer Aug 06 '17 at 21:45
  • 1
    I'm not totally sure of how you're handling your token when you authenticate a user in your client. So, since you're using axios, you need to explicitly set your request authorization which you can include in the subsequent request. check [this](https://stackoverflow.com/questions/43014034/setting-authorization-header-in-axios) – Rowland Aug 06 '17 at 22:01
  • Hey @Rowland, so what exactly I need to set in my Authorization header? This is my first time using passport.js, I don't know what I should store as "token". After my successful /login I can see the "set-cookie:" property as response headers, I can access it through document.cookie, sending it to the server in the subsequent request doesnt work too. – Jean Bauer Aug 06 '17 at 23:39

1 Answers1

4

So, after some time I could find an answer:

Server sends SetCookie header then the browser handle to store it, and then the cookie is sent with requests made to the same server inside a Cookie HTTP header.

I had to set withCredentials: true in my client. (axios.js)

const config = {
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json',
  },
};

axios.put(url, { page: '123' }, config)
  .then(res => console.log('axios', res))
  .catch(err => console.log('axios', err));

Then I had CORS problems.

So I added this to my express server:

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();
  }
});
Jean Bauer
  • 101
  • 1
  • 7