0

I'm creating a small MERN app for signup, login and after successful login, it shows their profile.

1. I want the user to log-in and if it's successful I will send the user._id to the react app and redirect it to profile/user._id

2. At the profile page in the ComponentDidMount method, I will do a get-request to get the user-data from my server using it's user._id.

3. In this get-request, I want to check if this user has an active session or not so that even if someone uses an URL: profile/some_user_id it will always check for an active session.

My question is:

1. Do I need to explicitly send the cookie to the client if yes then how or express-session will do it for me.

2. After the solution to 1 how can I access this saved data int\ the session when I do /profile/id get-request.

My app.js

require('./passport')(passport);

app.use(cookieParser());
//Express session
app.use(
    session({
      secret: 'secret',
      resave: true,
      saveUninitialized: false,
      cookie: { maxAge: 60*60*1000 },
    })
);

app.use(passport.initialize());
app.use(passport.session());


app.post('/login', (req, res, next) => {
    passport.authenticate('local', (err, user, info) => {
        if(err) {
            res.status(203).send(err);
        } else {
            if(user) {
                req.login(user, err => {
                    req.session.user = user;
                    console.log(req.session);
                    res.status(200).send(user._id);
                })
            } else {
                res.status(202).send(info);
            }
        }
    })(req, res, next);
});

app.get('/profile/:id', (req, res, next) => {
    const id = req.params.id;
    console.log(req.session);
    res.send("session is running");
})

My passport.js

passport.use(
        new LocalStrategy({usernameField: 'email', passwordField: 'password'}, (email, password, done) => {
            // Match User
            User.findOne({email: email}, (err, user) => {
                    if(err) {
                        return done(err);
                    }
                    if(!user) {
                        return done(null, false, { msg: 'Input data incorrect!'})
                    }
                    // Match Password
                    bcrypt.compare(password, user.password, (err, isMatch) => {
                        if(err) throw error;
                        if(isMatch) {
                            return done(null, user);
                        } else {
                            return done(null, false, { msg: "Input data incorrect!"})
                        }
                    });
                })
        }) 
    );
    
    passport.serializeUser((user, done) => {
        done(null, user.id);
      });
      
    passport.deserializeUser((id, done) => {
        User.findById(id, (err, user) => {
            done(err, user);
        });
    }); 

console.log(req.session) in the '/login' post request.

Session {
  cookie: {
    path: '/',
    _expires: 2020-07-03T18:44:55.179Z,
    originalMaxAge: 3600000,
    httpOnly: true,
    secure: false
  },
  passport: { user: '5ef7a8b55570c353bc1aef12' },
  user: {
    _id: 5ef7a8b55570c353bc1aef12,
    email: 'mukeshgupta202000@gmail.com',
    userName: 'asdd',
    password: '$2b$10$wzF6uwxcFNHgi4NdNBL5A.wEAs4W14zQ8YpEboPJWttvRaIO6MXCq',
    createdAt: 2020-06-27T20:14:45.303Z,
    updatedAt: 2020-06-27T20:14:45.303Z,
    __v: 0
  }
}

console.log(req.session)

console.log(req.session.user) in the '/user/:id' getrequest.

Session {
  cookie: {
    path: '/',
    _expires: 2020-07-03T18:44:57.514Z,
    originalMaxAge: 3600000,
    httpOnly: true,
    secure: false
  }
}
undefined

1 Answers1

0

After being stuck for a few days I got the solution.

1. No you don't need to explicitly send the cookie to your client but you need to save your user data on your own.

req.session.user = userLoggedIn;

2. And to access this userLoggedIn data in a different route you need to use the same object:

req.session.user

The reason the above code didn't work was because of CORS.

To make it work just you need to explicitly tell the cors() in your express app whether or not cross-site Access-Control requests should be made using credentials such as cookies and where to send the cookie.

This can be done by the following code:

Server-Side

const corsOptions = {
    origin: 'http://localhost:3001',  //Your Client, do not write '*'
    credentials: true,
};
app.use(cors(corsOptions));

Client-side (if using axios)

axios.method('url', data(if needed), {withCredentials: true})

This will tell the browser to send the cookie on each request.

For other request-response libraries visit this answer.