Tips for maintaining a user's session post-login with Passport and Express JS

I recently set up a node backend using express and integrated Passport for authentication purposes. My application has a route called /login for logging in and another route called /me to retrieve information about the currently logged in user.

Below is the code snippet for these routes:

//auth_routes.js
const express = require('express');
const { Users } = require('../database/models');

const router = express.Router();

router.post("/login", async (req, res, next) => {
  try {
    const user = await Users.findOne({ where: { email: req.body.email } });
    if (!user) {
      res.status(401).send("Incorrect username and/or password");
    }
    else if (!await user.correctPassword(req.body.password)) {
      res.status(401).send("Incorrect username and/or password");
    }
    else {
      console.log("LOGIN", req.sessionID)
      req.login(user, err => {
        (err ? next(err) : res.json(user))
      });
    }
  }
  catch (err) {
    next(err);
  }
});


router.get('/me', (req,res) => {
  console.log("ME SESSION", req.sessionID)
  if (req.user) {
    res.json(req.user);
  } else {
    res.status(401).send("Not logged in");
  }
});

module.exports = router;

This is how I initialize passport:

const express = require('express')
const cors = require('cors')
const morgan = require('morgan')
const passport = require('passport')
const bodyParser = require('body-parser')
const session = require('express-session')

const db = require('./database')
const api_routes = require('./routes/api_routes')

const SequelizeStore = require('connect-session-sequelize')(session.Store)
const sessionStore = new SequelizeStore({ db })
const app = express()
const PORT = process.env.PORT || 5000

passport.serializeUser((user,done) => {
  console.log("in serialize", user.id)
  return done(null,user.id);
});

passport.deserializeUser(async (id,done) => {
  console.log("in deserialize", id)
  try {
    const user = await db.models.Users.findByPk(id);
    done(null,user);
  } catch (err) {
    done(err);
  }
});

const configureApp = () => {
    app.use(cors({origin:'http://localhost:3001',credentials: true}));
    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', 'Origin, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, X-Response-Time, X-PINGOTHER, X-CSRF-Token,Authorization');
      if (req.method === "OPTIONS") {
          return res.status(200).end();
      } else {
          next();
      }
  });
    app.use(bodyParser.json())
    app.use(bodyParser.urlencoded({extended: true}))
    app.use(morgan('dev'))

    app.use(
      session({
        secret: process.env.SECRET || "SUPER SECRET",
        resave: false,
        saveUninitialized: false,
        store: sessionStore,
        cookie: {secure: false}
      })
    )
    app.use(passport.initialize())
    app.use(passport.session())
    app.use('/api', api_routes)

    app.use((err, req, res, next) => {
      console.error(err);
      console.error(err.stack);
      res.status(err.status || 500).send(err.message || "Internal server error");
    })
}

const startListening = () => {
  app.listen(PORT, () => console.log(`Listening on PORT ${PORT}`))
}

const syncdb = async () => {
  await db.sync({force: true});
}

const bootApp = async () => {
  await sessionStore.sync();
  await syncdb();
  await configureApp();
  await startListening();
}

bootApp();

My observation so far indicates that when I use Postman to send the post request to /login and the get request to /me, everything functions as expected with matching session IDs. However, upon testing from the frontend, users are successfully logged in but encounter a 401 error during the subsequent get request to /me. Additionally, the session IDs differ between the login request and the me request.

Here's some of my client-side code implemented with Redux and Axios:

export const login = login => async dispatch => {
  try {
    let { data } = await axios.post('http://lacolhost.com:5000/api/auth/login', login);
    console.log(data);
    dispatch({type: 'SAVE_RESPONSE', payload: data});
  } catch (err) {
    console.error("Error logging in", err);
    dispatch({ type: 'SAVE_RESPONSE', payload: { message: 'Error communicating with server' }});
  }

export const getUser =  () =>  async (dispatch) => {
    try {

      const { data } = await axios.get('http://lacolhost.com:5000/api/auth/me', {withCredentials: true})
      dispatch({
        type: 'SELECT_USER',
        payload: data
      })
    } catch (err) {
      console.log(err);
    }
  }

If anyone has insights into what might be causing this discrepancy and how it can be resolved, I would greatly appreciate your assistance. Thank you!

Answer №1

If you are utilizing axios for API requests in your front-end, remember to include the {withCredentials: true} configuration.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

If an iframe contains a div with a particular class inside, then execute the following code

I need to dynamically add a class to the parent element if a specific class is present in its child. The issue: the content is within an iFrame and I'm not very proficient with jQuery. It doesn't necessarily have to be jQuery, any alternative m ...

Can an express server be utilized to update a page simultaneously for all of its users?

As I develop a web application, one of the features involves adding songs to a queue. The app consists of multiple rooms, each with its own properties, including a song queue stored as an array on the server. Using app.post, a new song URL is sent to the s ...

Caution: Attempting to access a non-existent 'sequelize' property within a circular dependency in the module exports

Issue Nodemon server.js [nodemon] 2.0.15 [nodemon] to restart at any time, enter `rs` [nodemon] watching path(s): *.* [nodemon] watching extensions: js,mjs,json [nodemon] starting `node server.js` Warning: connect.session() MemoryStore is not designe ...

Struggling with integrating API response formatting in React and updating state with the data

This is the content found in the file 'Search.js' import React, { Component } from 'react'; import * as BooksAPI from './BooksAPI' class Search extends Component{ constructor(props){ super(props); this.state={ ...

The custom classes I have created in Material UI are being overshadowed by the default classes provided by Material UI

I am trying to change the color of a TextField label to black when it is focused. I used classes in InputProps with a variable, but unfortunately, the default styling of material UI is taking precedence in chrome dev tools. Below is the code snippet. Pleas ...

Is it possible to create a component with a button that triggers the rendering of a different component?

I am struggling to implement an 'edit' button within a component that, upon clicking, should display a separate component known as a 'client edit modal'. I'm facing challenges in figuring out how to achieve this functionality. The ...

Node.js SQLite Store Default Path

app.use(session({ store: new SQLiteStore, secret:"xxxxxx", saveUninitialized: false, cookie: { maxAge: 60000 }, rolling: true, resave: true })); If you want to modify the default path for storing session files, you can specify the desired path ...

What is the process for integrating TypeScript compiling into a JavaScript application?

My project includes a build.js file that is responsible for building the project. It has two main objectives: Compile .ts files and store them in a new directory. Create an asar archive containing the compiled files. Since typescript (or tsc) is availabl ...

Tips on editing a file exclusively when a specific requirement is fulfilled

Looking for a way to implement a put method within an Express API that allows users to update a document conditionally? Consider this scenario: you have an Instance document with an attribute called executed, which is set to true if the instance has been e ...

Dealing with errors in a sequelize ORM query: Tips and tricks

Currently, I am implementing Sequelize ORM in my Node/Express project using Typescript. Within the database, there is a 'users' table with a unique column for 'email'. As part of my development process, I am creating a signIn API and ...

The PassportJS logged in feature always yields a result of zero

After successfully implementing passportJS in my application, I encountered an issue with the current connected user. When using (req.isAuthenticated()), it always returns "0". Here is the code snippet from auth.js: /* Passport - Sessions - Cookies D ...

What is the best way to choose a single item from an array using jQuery?

Within an array, I have IDs and descriptions like: var tablica = [{"3":"asdasd asd"},{"19":"asddas fff"},{"111111":"adas asf asdff ff"},{"4":"re"},{"5":"asdasd"},{"6":"we"},{"7":"asdasdgg"},{"9":"asdasdasd"},{"16":"sdads"},{"10":"asdgg"},{"11":"ggg"}]; ...

The collapsible list feature that includes the use of plus and minus signs is malfunctioning

Below is the script that I wrote to address this issue, but for some reason the + and - swapping is not functioning correctly. $('.showCheckbox').click(function(e) { var dynamicBox = $(this).attr('val'); var collapseSign = $(th ...

Move divs that are currently not visible on the screen to a new position using CSS animations

Upon entering the site, I would like certain divs to animate from an offscreen position. I came across this code snippet: $( document ).ready(function() { $('.box-wrapper').each(function(index, element) { setTimeout(function(){ ...

How can I use AJAX to transmit a 2D array to a PHP page and then display each dimension individually?

Recently, I created a webpage with multiple checkboxes. Using jQuery, I am able to fetch data from these checkboxes and store them in a two-dimensional array. Here is an excerpt of my code: HTML snippet: <input type="checkbox" name="checkboxs[]" pric ...

Tips for managing several Material UI Slide Components at once

Utilizing Material UI's Slide component, I have encountered an issue with my code. Upon hovering over a card, I intend for an individual slide to appear. However, the current implementation causes both slides to be displayed when hovering over any of ...

Guide on setting up create-next-app with version 12 instead of the latest version 13

For an upcoming Udemy course, I am required to develop a Next.js project. However, it specifically needs to be built using Next.js version 12 rather than the latest version 13. Does anyone know how I can achieve this? ...

Transmit the JavaScript array via AJAX to PHP server

Is it possible to transfer a JS array created using the .push function to another PHP file? I have included the code snippets for the two files involved, game.js and gallery.php. In Game.js: imgarray.push({"img_name": img_name,"x": x_value,"y": y_value,"w ...

Component in Next Js fails to pass props when using getInitialProps

I am facing some challenges with Next Js and could really use some assistance. We have a component where I am utilizing "getInitialProps" to pass props to it during the server-side rendering process. However, no matter what I try, the props do not seem to ...

Enhance your Django webpage with real-time updates using AJAX technology

[Revised for Clarity and Detail] The challenge I'm facing is related to the architecture of my project. I have multiple ideas on how to achieve my goal, but I'm stuck on identifying the correct or most efficient approach. To provide more context ...