Currently working on developing an e-commerce platform, both front and back-end. Using express and passport for a basic login/register system. The issue I'm facing is that every time a page with a request is accessed, a new session is created and stored in MongoDB server, resulting in multiple sessions being created as I navigate through different sections of the site.
The goal is to have sessions created ONLY after user authentication.
Below is a snippet of my code:
app.js:
import express from "express"
import mongoose from "mongoose"
import { Server } from "socket.io"
import { boxRouter } from "./routes/box.router.js"
import { productRouter } from "./routes/product.router.js"
import { cartRouter } from "./routes/cart.router.js"
import { userRouter, isLoggedIn } from "./routes/user.router.js"
import passport from "passport"
import initializePassport from "./passport.config.js"
import cors from 'cors'
import MongoStore from "connect-mongo"
import cookieParser from "cookie-parser"
import session from "express-session"
// const hostname = '0.0.0.0'
// const port = '10000'
export var app = express()
// const httpServer = app.listen(port, hostname, ()=>{ console.log("Server Up")})
const httpServer = app.listen(8080, ()=>{ console.log("Server Up")})
export const socketServer = new Server(httpServer)
app.use(cookieParser("mostsecretsecret"))
app.use(session({
store: MongoStore.create({
mongoUrl: 'blablabla',
mongoOptions: {useNewUrlParser: true, useUnifiedTopology: true},
ttl: 15
}),
cookie:{
maxAge: 7 * 24 * 60 * 60 * 1000,
},
secret: 'mysecret',
resave: true,
saveUnitialized: false
}))
initializePassport()
app.use(passport.initialize())
app.use(passport.session())
app.use(cors())
app.use(express.urlencoded({extended:true}))
app.use(express.json())
app.use('/api/boxes', boxRouter)
app.use('/api/products', productRouter)
app.use('/api/carts', cartRouter)
app.use('/api/users', userRouter)
var connectionString = "blablabla"
mongoose.set('strictQuery', false)
mongoose.connect(connectionString)
socketServer.on('connection', socket=>{
console.log("Nuevo cliente conectado.")
})
passport.config.js:
import passport from "passport";
import local from 'passport-local';
import { userModel } from './models/user.model.js'
import { createHash, isValidPassword } from "./utils.js";
import { cartManager } from "./managers/CartManager.js";
const LocalStrategy = local.Strategy
const initializePassport = ()=>{
passport.use('register', new LocalStrategy(
{passReqToCallback: true, usernameField: 'email'}, async(req, username, password, done)=>{
const { first_name, last_name, email, newsletter } = req.body
try{
let user = await userModel.findOne({email: username})
if(user){
console.log("El usuario ya existe")
return done(null, false)
}
let newCart = await cartManager.createCart()
const newUser = {
first_name,
last_name,
email,
password: createHash(password),
cartId: newCart.id,
newsletter,
role: 'user'
}
let result = await userModel.create(newUser)
return done(null, result)
}catch(err){
return done("Error al obtener el usuario: " + err)
}
}
))
passport.use('login', new LocalStrategy(
{usernameField: 'email'}, async(username, password, done)=>{
try{
const user = await userModel.findOne({email: username})
if(!user){
console.log("El usuario no existe")
return done(null, false)
}
if(!isValidPassword(user,password)) return done(null, false)
return done(null, user)
}catch(err){
return done(err)
}
}
))
passport.serializeUser((user, done)=>{
done(null, user._id)
})
passport.deserializeUser(async(id, done)=>{
let user = await userModel.findById(id)
done(null, user)
})
}
export default initializePassport
user.router.js:
import { Router } from 'express';
import passport from 'passport';
export const userRouter = Router()
export function isLoggedIn(req, res, next){
if(req.session.user){
return next()
}
return res.status(401).send('Error de autorización.')
}
userRouter.post('/register', passport.authenticate('register', {}), async (req, res)=>{
try {
res.send('Success')
} catch (error) {
res.status(400).send({
status: 'error',
message: error.message
})
}
})
userRouter.post('/login', passport.authenticate('login', {}), async (req, res)=>{
try {
if(!req.user){
return res.status(401)
}
req.session.user = {
first_name: req.user.first_name,
last_name: req.user.last_name,
email: req.user.email,
role: req.user.role
}
res.send('Success')
} catch (error) {
res.status(400).send({
status: 'error',
message: error.message
})
}
})
userRouter.get('/logout', (req, res)=>{
try {
req.session.destroy(err=>{
if(err) res.status(500)
})
} catch (error) {
res.status(400).send({
status: 'error',
message: error.message
})
}
})
userRouter.get('/check-login', isLoggedIn, (req, res) => {
try {
res.status(200).send('Usuario logueado');
} catch (error) {
res.status(400).send({
status: 'error',
message: error.message
})
}
});
After browsing through 3 pages, multiple sessions are created as shown in this image of my database: https://i.sstatic.net/4rki3.png